(simplified version of this)
The simple but not recommended approach:
from django.conf.urls.defaults import * from mysite.views import hello, current_datetime, hours_ahead urlpatterns = patterns('', (r'^hello/$', hello), (r'^time/$', current_datetime), (r'^time/plus/(\d{1,2})/$', hours_ahead), )
Can be written as:
from django.conf.urls.defaults import * from mysite import views urlpatterns = patterns('', (r'^hello/$', views.hello), (r'^time/$', views.current_datetime), (r'^time/plus/(d{1,2})/$', views.hours_ahead), )
or
from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^hello/$', 'mysite.views.hello'), (r'^time/$', 'mysite.views.current_datetime'), (r'^time/plus/(d{1,2})/$', 'mysite.views.hours_ahead'), )
or
from django.conf.urls.defaults import * urlpatterns = patterns('mysite.views', (r'^hello/$', 'hello'), (r'^time/$', 'current_datetime'), (r'^time/plus/(d{1,2})/$', 'hours_ahead'), )
Patterns can be split as:
from django.conf.urls.defaults import * urlpatterns = patterns('mysite.views', (r'^hello/$', 'hello'), (r'^time/$', 'current_datetime'), (r'^time/plus/(\d{1,2})/$', 'hours_ahead'), ) urlpatterns += patterns('weblog.views', (r'^tag/(\w+)/$', 'tag'), )
Named and non-named groups
(r'^articles/(\d{4})/$', views.year_archive), # become (r'^articles/(?P<year>\d{4})/$', views.year_archive),
NOTE: Each captured argument is sent to the view as a plain Python Unicode string
Passing Extra Options to View Functions
(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}), # and the function will be (in views.py) def foobar_view(request, template_name):
Faking Captured URLconf Values
urlpatterns = patterns('', (r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}), (r'^mydata/(?P<month>\w{3})/(?P<day>\d\d)/$', views.my_view), )
Special-Casing Views
urlpatterns = patterns('', # ... # auth/user/add will match the first one and execute views.user_add_stage ('^auth/user/add/$', views.user_add_stage), # myblog/entries/add will match the second one ('^([^/]+)/([^/]+)/add/$', views.add_stage), # ... )
Variable arguments with asterisks
def foo(*args, **kwargs): foo(1, 2, name='Adrian', framework='Django') Positional arguments are: (1, 2) Keyword arguments are: {'framework': 'Django', 'name': 'Adrian'}
# single asterisk in front of a parameter in a function definition → any positional arguments to that function will be rolled up into a single tuple.
# two asterisks in front of a parameter in a function definition → any keyword arguments to that function will be rolled up into a single dictionary.
Wrapping View Functions
If repeating a lot of common code (e.g. authenticate check), we can build a view wrapper:
def requires_login(view): def new_view(request, *args, **kwargs): if not request.user.is_authenticated(): return HttpResponseRedirect('/accounts/login/') return view(request, *args, **kwargs) return new_view
and then in url.conf
urlpatterns = patterns('', (r'^view1/$', requires_login(my_view1)), (r'^view2/$', requires_login(my_view2)), (r'^view3/$', requires_login(my_view3)), )
Including Other 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'), )
Note: include() do not have a $ (end-of-string match character) but do include a trailing slash
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'), )
/weblog/2007/ will match first line in the main urls.conf (strip the weblog/) and send the rest (2007/) to the mysite.blog.urls (where it will match first line)
Note: if you add extra URLconf options
urlpatterns = patterns('', (r'^blog/', include('inner'), {'blogid': 3}), )
or capture parameters
urlpatterns = patterns('', (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')), )these will be sent to EVERY view function within that URLconf.