Django之URL(路由)分发机制
本质
(1):它的本质是 URL 模式以及要为该 URL 模式调⽤的视图函数之间的映射表。
django-admin.py startproject 运⾏时,该脚本会⾃动为你建了⼀份 URLconf(URL configuration)(即 urls.py ⽂件)。
由于它是纯Python代码(pure Python code),可以动态创建(Dynamically Constructed).
(2):Django 把这个记录到ROOT_URLCONF 中
ROOT_URLCONF
Default: Not defined
⾃动创建的settings.py包含⼀个ROOT_URLCONF配置⽤来指向⾃动产⽣的urls.py. 打开⽂件settings.py你将看到如下:
ROOT_URLCONF = 'mysite.urls'
# 相对应的⽂件是mysite/urls.py
⼀个字符串代表完整的Python导⼊路径URLconf根,如’mydjangoapps.urls’,可以覆盖根据每条请求通过设置属性urlconf传⼊的HttpRequest对象。
(3):当访问 URL /hello/ 时,Django 根据 ROOT_URLCONF 的设置装载 URLconf 。然后按顺序逐个匹配URLconf⾥的URLpatterns,直到到⼀个匹配的。当到这个匹配的URLpatterns就调⽤相关联的view函数,并把 HttpRequest 对象作为第⼀个参数。
(4):视图函数必须返回⼀个HttpResponse,Django转换HttpResponse为⼀个适合的HTTP response,以Web page显⽰出来
patterns()函数
urlpatterns should be a Python list,in the format returned by the function patterns()
#f.urls.defaults.patterns()
patterns(prefix, pattern_description, ...)
The first arguement to patterns() is a string prefix(前缀)
The remaining(剩余的) arguements should be tuples :
⼀般我们将patterns()函数返回的值保存到 urlpatterns变量中.
Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function.
视图函数使⽤HttpRequest对象作为第⼀个参数,任何值捕获的正则表达式作为其他参数。
def myblog(request,id,name):
pass
url()函数
You can use the url() function, instead of a tuple, as an argument to patterns()
django admin 自定义页面语法:
url(regex, view, kwargs=None, name=None, prefix='')
urlpatterns =patterns('djtest.views',
(r'^json/$','json'),
url(r'^geturl/$','geturls',name='get_urls'),
)
#如果patterns()没有前缀的话,也可这样:
urlpatterns += patterns('',
url(r'^geturl2/$','geturl2',name='geturl2_test',prefix='djtest.views'),
)
include()函数
include(<module or pattern_list>)
your urlpatterns can “include” other URLconf modules!
通常⽤于分类处理,使项⽬中urls⾼度统⼀.如:
urlpatterns +=patterns('',
(r'^blog/',include('myblog.urls')), #myblog app 中urls
(r'^manage/',include('manager.urls')), #manage app 中urls
)
注意:
(1)include() 的正则表达式并不包含⼀个 $ (字符串结尾匹配符),但是包含了⼀个斜杆/。
(2)每当Django遇到 include() 时,它将截断匹配的URL,并把剩余的字符串发往包含的URLconf作进⼀步处理。
如在 myblog.app中urls如下:
#myblog.app 中的urls
urlpatterns =patterns('myblog.views',
(r'^index/$','index'), #博客⾸页
)
那么就讨论⼀下include()匹配的模式吧:
(1)不含变量参数
如在url输⼊框中输⼊则,它会截取include()中匹配的url,这⾥是”blog” 接下来到了宿主了也就是myblog.urls,那么剩余的部分,也就是”index” 去匹配myblog.urls中的url模式。
(2)含有变量参数(如命名组)
#root urls
urlpatterns += patterns('',
(r'^(?P<username>\w+)/blog/',include('blog.urls')),
)
#blog.urls
urlpatterns = patterns('blog.views',
(r'^index/$','index'),
(r'^other/$','other'),
)
#blog.views
def index(request):
return HttpResponse('ok')
#参数变量处理
def other(request,username):
return HttpResponse(username)
被捕获的 username 变量将传递给被包含的 URLconf,进⽽传递给那个URLconf中的每⼀个视图函数。
那么在浏览器输⼊:
则输出:BeginMan
更复杂点:
(r'^blog/(?P<username>\w+)/(?P<user_id>\d+)/',include('blog.urls'))
#.....
def index(request,username,user_id):
return HttpResponse('ok:%s,%s' %(username,user_id))
输⼊:
输出:ok:BeginMan,20
注意后⾯不要忘了去匹配blog urls的哪个urls。如(r'^index/$’)
url⾼级配置
参考:
1、命名组:
⽆命名正则表达式组,即,在我们想要捕获的URL部分上加上⼩括号,Django 会将捕获的⽂本作为位置参数传递给视图函数。
命名正则表达式组来捕获URL,并且将其作为关键字参数传给视图。
命名的正则表达式组的语法是:
(?P<name>pattern)
name:组名称
pattern:匹配的某个模式,常见有:
Symbol Matching
.任意单个字符
\d匹配任意数字
[A-Z]匹配A-Z任意⼤写字母
[a-z]匹配a-z任意⼩写字母
[A-Za-z]匹配a-z任意字母不论⼤⼩写
+匹配⼀个或多个(如:\d+)
[^xxx]+匹配⼀个或多个不为xxx的(如[^name]+)
?匹配零个或⼀个(如:\d?)
*匹配零个或更多(如:\d*)
{a,b}匹配介于a ,b之间(如:\d{1,3}⼀个或两个或三个数字)
实例如下:
('^position/(\d{4})/(\d{2})/$','position'), #⽆命名正则表达式组
('^name/(?P<year>\d{4})/(?P<month>\d{2})/$','name'), #命名组
则输⼊地址:、在相应视图函数中进⾏处理
#以位置参数的形式,如果位置改变,如(request,month,year),则相应的值也会随之改变def position(request,year,month):
return HttpResponse('position:%s--%s' %(year,month))
#输出:position:2013--10
#关键字参数,key-value映射关系,与位置⽆关,所以当位置改变,值不变
def name(request,month,year):
return HttpResponse('name:%s--%s' %(year,month))
2、传递额外的参数到视图函数中
URLconf⾥⾯的每⼀个模式都可以包含第三个数据:⼀个关键字参数的字典。
('^foo/$','commonView',{'name':'foo','age':22}),
('^bar/$','commonView',{'name':'bar','age':12}),
def commonView(request,name,age):
return HttpResponse('name:%s--age:%s' %(name,age))
则输⼊:、则输出: bar、 foo
常见应⽤是传递模板:
# urls.py
f.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
(r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)
# views.py
from django.shortcuts import render_to_response
dels import MyModel
def foobar_view(request, template_name):
m_list = MyModel.objects.filter(is_new=True)
return render_to_response(
template_name,
{'m_list': m_list})
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论