pythondjangourlurlconf

Why do some includes in Django need strings, and others variable names?


Referring to the Django Book, chapter 3:

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^mysite/', include('mysite.foo.urls')),
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    # url(r'^admin/', include(admin.site.urls)),
)

What determines why one thing is included as a string, and another as regular variable? Why admin.site.urls but not 'admin.site.urls'? All other includes are included as strings... I see no logical pattern here.


Solution

  • First of all, the first pattern ('mysite.views.home' -> a view function) is deprecated in 1.8: it led to all kinds of trouble.

    As for the rest, it generally works both. 'mysite.foo.urls' is resolved to include the patterns in the module mysite.foo.urls, but from mysite.foo import urls as foo_urls; include(foo_urls) works as well. The string-based imports are mostly a historical artifact that hasn't been removed, but it is convenient and doesn't have any real drawbacks as the module is immediately imported (and thus, any ImportError is easily traceable to the url config).

    admin.site.urls is different, because admin.site.urls is not a module, but site is an object and urls is an attribute. For that reason, string-based imports of admin.site.urls won't work, and you have to use the second method.

    As a last note, the warning at the beginning of the Django Book, stating that it is extremely out of date, is outdated. More up-to-date resources, such as the official documentation (one of the best official documentations I know), would be preferable.