Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 647
codyc4321 Avatar asked Apr 19 '15 22:04

codyc4321


People also ask

What is the basic idea of include in Django?

include() A function that takes a full Python import path to another URLconf module that should be “included” in this place. Optionally, the application namespace and instance namespace where the entries will be included into can also be specified.

Which characters are illegal in template variable names in Django?

Variable names consist of any combination of alphanumeric characters and the underscore ( "_" ) but may not start with an underscore, and may not be a number.

What does {% %} mean in Django?

{% %} and {{ }} are part of Django templating language. They are used to pass the variables from views to template. {% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.


2 Answers

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.

like image 195
knbk Avatar answered Oct 17 '22 14:10

knbk


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'),
    ]
like image 30
mcastle Avatar answered Oct 17 '22 14:10

mcastle