El libro de Django 1.0

8.2. Incluyendo otras URLconfs

Si tu intención es que tu código sea usando en múltiples sitios implementados con Django, debes considerar el organizar tus URLconfs en una manera que permita el uso de inclusiones.

Tu URLconf puede, en cualquier punto, "incluir" otros módulos URLconf. Esto se trata, en esencia, de "enraizar" un conjunto de URLs debajo de otras. Por ejemplo, esta URLconf incluye otras URLconfs:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^weblog/', include('mysite.blog.urls')),
    (r'^photos/', include('mysite.photos.urls')),
    (r'^about/$', 'mysite.views.about'),
)

Existe aquí un detalle importante: en este ejemplo, la expresión regular que apunta a un include() no tiene un $ (carácter que coincide con un fin de cadena) pero si incluye una barra al final. Cuando Django encuentra include(), elimina todo el fragmento de la URL que ya ha coincidido hasta ese momento y envía la cadena restante a la URLconf incluida para su procesamiento subsecuente.

Continuando con este ejemplo, esta es la URLconf mysite.blog.urls:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'),
    (r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'),
)

Con esas dos URLconfs, veremos aquí cómo serían manejadas algunas peticiones de ejemplo:

  • /weblog/2007/: En la primera URLconf, el patrón r'^weblog/' coincide. Debido a que es un include(), Django quita todo el texto coincidente, que en este caso es 'weblog/'. La parte restante de la URL es 2007/, la cual coincide con la primera línea en la URLconf mysite.blog.urls.
  • /weblog//2007/: En la primera URLconf, el patrón r'^weblog/' coincide. Debido a que es un include(), Django quita todo el texto coinciente, que en este caso es weblog/. La parte restante de la URL es /2007/ (con una barra inicial), la cual no coincide con ninguna de la líneas en la URLconf mysite.blog.urls.
  • /about/: Esto coincide con el patrón de la vista mysite.views.about en la primera URLconf, demostrando que puedes combinar patrones include() con patrones no include().

8.2.1. Cómo trabajan los parámetros capturados con include()

Una URLconf incluida recibe todo parámetro que se haya capturado desde las URLconf padres, por ejemplo:

# root urls.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
)
# foo/urls/blog.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^$', 'foo.views.blog_index'),
    (r'^archive/$', 'foo.views.blog_archive'),
)

En este ejemplo, la variable capturada username() es pasada a la URLconf incluida y, por lo tanto, a todas las funciones vista en dicha URLconf.

Notar que los parámetros capturados serán pasados siempre a todas las líneas en la URLconf incluida, con independencia de si la vista de la línea realmente acepta esos parámetros como válidos. Por esta razón esta técnica solamente es útil si estás seguro de que cada vista en la URLconf incluida acepta los parámetros que estás pasando.

8.2.2. Cómo funcionan las opciones extra de URLconf con include()

De manera similar, puedes pasar opciones extra de URLconf a include() así como puedes pasar opciones extra de URLconf a una vista normal — como un diccionario. Cuando haces esto, las opciones extra serán pasadas a todas las líneas en la URLconf incluida.

Por ejemplo, los siguientes dos conjuntos de URLconfs son funcionalmente idénticos.

Conjunto uno:

# urls.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^blog/', include('inner'), {'blogid': 3}),
)
# inner.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^archive/$', 'mysite.views.archive'),
    (r'^about/$', 'mysite.views.about'),
    (r'^rss/$', 'mysite.views.rss'),
)

Conjunto dos:

# urls.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^blog/', include('inner')),
)
# inner.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
    (r'^about/$', 'mysite.views.about', {'blogid': 3}),
    (r'^rss/$', 'mysite.views.rss', {'blogid': 3}),
)

Como en el caso de los parámetros capturados (sobre los cuales se explicó en la sección anterior), las opciones extra se pasarán siempre a todas las líneas en la URLconf incluida, sin importar de si la vista de la línea realmente acepta esas opciones como válidas. Por eta razón esta técnica es útil sólo si estás seguro que todas las vistas en la URLconf incluida acepta las opciones extra que estás pasando.