10

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.

Jesuisme
  • 1,805
  • 1
  • 31
  • 41
codyc4321
  • 9,014
  • 22
  • 92
  • 165

5 Answers5

7

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.

knbk
  • 52,111
  • 9
  • 124
  • 122
  • What would you do to call a view there then past dj 1.8? import the view and call it like `url(r'^$', view_but_not_as_string, name='home')`? – codyc4321 Apr 21 '15 at 16:25
  • 1
    Without the include: `from mysite.views import home; ...url(r'^$', home, name='home'),...`. `include()` is only to add other patterns nested in the current pattern. – knbk Apr 21 '15 at 16:27
4

If you're passing to include() a list of url() instances, then you don't use a string (see Include() docs and Including other URLconfs docs). In your admin urls example, admin.site.urls refers to a list of url instances. See the get_urls method in the source code (which provides the list of url instances referred to by admin.site.urls).

def get_urls(self):
    ...
    # Admin-site-wide views.
    urlpatterns = [
        url(r'^$', wrap(self.index), name='index'),
        url(r'^login/$', self.login, name='login'),
        url(r'^logout/$', wrap(self.logout), name='logout'),
        url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
        url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
            name='password_change_done'),
        url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
        url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
            name='view_on_site'),
    ]
mcastle
  • 2,882
  • 3
  • 25
  • 43
3

You are right this was a little confusing. They changed this in Django 1.8, so now they only support including normal variables.

Read more about this in Django 1.8 release note.

Domen Blenkuš
  • 2,182
  • 1
  • 21
  • 29
3

You must to put a path with a string into the function include(). But admin.site.urls is like a string because at the begining of code, you have a import

Tanorix
  • 230
  • 2
  • 16
3

From the Django 1.8 documentation, include() can take as an argument a module OR a module name

https://docs.djangoproject.com/en/1.8/ref/urls/#include

The line

from django.contrib import admin

imports the admin module. Thus, it can be used directly as an argument for include. The other include() methods have string arguments that name other URLconfs.

Jesuisme
  • 1,805
  • 1
  • 31
  • 41