一、师法资源
Django资料少之又少,庆幸有很多优秀的教程,如:http://djangobook.py3k.cn/2.0/chapter08/;本文博取其中知识点,并加以总结和拓展。
如果你也是个Django、Python爱好者,请加入【Django中国社区】或者【下方QQ群】吧
二、Url常用配置方法
1、有些小问题:
比如说,我的项目里面有两个app,在url中都这样导入:
1 from login.views import * 2 from demo.views import *
恰好,在一个url中,我使用了一个视图函数叫做demo1,当然我可以这样写:
1 ......... 2 urlpatterns +=patterns('', 3 (r'^demo1/$',demo1), 4 )
虽然简洁,但是里面暗藏着BUG,比如说,两个views中都有一个同名的视图函数,如demo1,如下:
1 login.views: 2 def demo1(request): 3 return HttpResponse('I am a login.views.demo1')
1 demo.views: 2 def demo1(request): 3 return HttpResponse('I am demo.views.demo1')
那么该调用哪一个呢,事实是这样的,由于Url从上倒下,相同的部分会被后者覆盖掉,所以它只调用最后面的视图函数,也即是:from demo.views import *
总结:
这个例子告诉我们:对于多个app下的视图函数,尽量保证不要重名,或者传入一个包含模块名和函数名的字符串形式,或传入模块名.函数名的形式显式界定。
2、使用命名组
这里需要弄清楚三点:
(1)、关键字参数和位置参数
(2)、语法结构
(3)、匹配算法以及注意事项
第一点DjangoBook说的很清楚,第二点,在 Python 正则表达式中,命名的正则表达式组的语法是(?P<name>pattern);这里 name 是组的名字,而 pattern 是匹配的某个模式。
3、传递额外的参数到视图函数中
URLconf里面的每一个模式都可以包含第三个参数: 一个关键字参数的字典:
1 # urls.py 2 3 from django.conf.urls.defaults import * 4 from mysite import views 5 6 urlpatterns = patterns('', 7 (r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}), 8 (r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}), 9 ) 10 11 # views.py 12 13 from django.shortcuts import render_to_response 14 from mysite.models import MyModel 15 16 def foobar_view(request, template_name): 17 m_list = MyModel.objects.filter(is_new=True) 18 return render_to_response(template_name, {'m_list': m_list})
4、伪造捕捉到的URLconf值
这个很灵活,让一个视图函数办多件事,其实也就是利用额外参数进行特定处理而已,如下:
1 urlpatterns +=patterns('', 2 (r'^mydata/birthday/$','demo.views.mydata',{'month':'Jan','day':'06'}), #My Birthday 3 (r'^mydata/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$','demo.views.mydata'), #Other Date 4 )
1 def mydata(request,month,day): 2 return HttpResponse('%s/%s' %(month,day))
5、捕捉值与额外参数之间的优先级
6、从URL中捕获的文本
看上面实例中,可能回想怎么不是日期时间类型或整型而是使用%s呢,因为每一个被捕获的参数作为Python字符串来发送,而不管正则表达式中的格式,所以如果用的话,还要进行适当处理才行。
7、include()的工作原理及注意事项
应用程序基于多个django站点,应该考虑到URLConfig包含【include】的方式来处理urls。
1 from django.conf.urls.defaults import * 2 urlpatterns = patterns('', 3 (r'^weblog/', include('mysite.blog.urls')), 4 (r'^photos/', include('mysite.photos.urls')), 5 (r'^about/$', 'mysite.views.about'), 6 )
重要的地方:指向 include() 的正则表达式并不包含一个 $ (字符串结尾匹配符),但是包含了一个斜杆。每当 Django 遇到 include() 时,它将截断匹配的URL,并把【剩余】的字符串发往被包含的 URLconf 作进一步处理。
1 被包含的 URLconf mysite.blog.urls : 2 from django.conf.urls.defaults import * 3 urlpatterns = patterns('', 4 (r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'), 5 (r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'), 6 )
当请求:/weblog/2011/ 时,首先是 (r'^weblog/', include('mysite.blog.urls'))匹配/weblog/ , 由于使用include,正则停止匹配,并将 2011/发送到mysite.blog.urls中;
(r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail') 可以匹配 2011/ ,于是将执行 mysite.blog.views.year_detail 视图,并传递参数 2011
一个被包含的URLconf 接收任何来自parent URLconfs 的被捕获的参数,比如:
1 # root urls.py 2 from django.conf.urls.defaults import * 3 4 urlpatterns = patterns('', 5 (r'^(?P\w+)/blog/', include('foo.urls.blog')), 6 ) 7 8 # foo/urls/blog.py 9 10 from django.conf.urls.defaults import * 11 12 urlpatterns = patterns('', 13 (r'^$', 'foo.views.blog_index'), 14 (r'^archive/$', 'foo.views.blog_archive'), 15 )
在这个例子中,被捕获的 username 变量将传递给被包含的 URLconf,进而传递给那个
URLconf 中的 每一个 视图函数。
注意,这个被捕获的参数 总是 传递到被包含的URLconf 中的 每一 行,不管那些行对应的
视图是否需要这些参数。因此,这个技术只有在你确实需要那个被传递的参数的时候才显得
有用。
相似的,你可以传递额外的 URLconf 选项到 include() , 就像你可以通过字典传递额外的URLconf 选项到普通的视图。当你这样做的时候,被包含 URLconf 的 每一 行都会收那些额外的参数。 比如,下面的两个 URLconf 在功能上是相等的。
1 # urls.py 2 from django.conf.urls.defaults import * 3 4 urlpatterns = patterns('', 5 (r'^blog/', include('inner'), {'blogid': 3}), 6 ) 7 8 # inner.py 9 from django.conf.urls.defaults import * 10 11 urlpatterns = patterns('', 12 (r'^archive/$', 'mysite.views.archive'), 13 (r'^about/$', 'mysite.views.about'), 14 (r'^rss/$', 'mysite.views.rss'), 15 16 ) 17 18 19 # urls.py 20 from django.conf.urls.defaults import * 21 22 urlpatterns = patterns('', 23 (r'^blog/', include('inner')), 24 ) 25 26 # inner.py 27 from django.conf.urls.defaults import * 28 29 urlpatterns = patterns('', 30 (r'^archive/$', 'mysite.views.archive', {'blogid': 3}), 31 (r'^about/$', 'mysite.views.about', {'blogid': 3}), 32 (r'^rss/$', 'mysite.views.rss', {'blogid': 3}), 33 )
这个例子和前面关于被捕获的参数一样(在上一节就解释过这一点),额外的选项将 总是传递到被包含的 URLconf 中的 每一 行,不管那一行对应的视图是否确实作为有效参数接这些选项,因此,这个技术只有在你确实需要那个被传递的额外参数的时候才显得有用。