Django中URL的解析和反查
add by zhj:
如果想用reverse(namespace1:namespace2:...:namespaceN:name)反查url(注意:用reverse('polls:index')方法和{% url 'polls:index' %}获取到的是url中的path部分,要自己加上domain才是完整的url),那要做下面两点。
1. 该url路径上用到的所有url()方法中必须加name参数,如果url()方法中有include(),那不用加name参数。
name相当于文件,同一目录下的文件不能重名,即任何一个patterns(),它里面的各个url()的name参数不能相同。
2. 该url路径上用到的所有include()方法中必须namespace参数。
include相当于目录,同一父目录下的目录不能重名,即任何一个patterns(),它里面的各个url()中的include()的namespace不能重名
下面是正文
1. URL的解析
该部分来自http://blog.csdn.net/hackerain/article/details/40701099
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
url(r'^articles/2003/$', 'news.views.special_case_2003'),
url(r'^articles/(\d{4})/$', 'news.views.year_archive'),
)
urlpatterns += patterns('',
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
url(r'model/', include('model_test.urls')),
)
这段代码就是一个URL Dispatcher的例子,它定义了URL和View之间的映射。在Django中的主配置文件中,用ROOT_URLCONF配置项来指定根URLconf,从根URLconf开始,逐条进行匹配,直到找到匹配项为止。
在上面例子中,我们可以看到有3个方法:patterns, url, include。url方法构建了一个URL到View方法的映射关系对象,patterns将这些映射关系对象组织成为一个python的列表,那include是做什么的呢?它就是我们上面说到的“树”结构关系的联系者,include会关联其他的URLconf到本URLconf,也就是说include关联的是孩子节点。整个URL dispatcher体系,就是由这三个方法构建起来的,下面我们重点来介绍这三个方法,了解了这三个方法,整个URL映射机制就会非常清楚了。
def url(regex, view, kwargs=None, name=None, prefix=''):
pass def patterns(prefix, *args):
pass def include(arg, namespace=None, app_name=None):
pass
url()
先来看下最重要的url()方法。第一个参数regex是代表URL的正则表达式,第二个参数指定了和该正则表达式映射的View,此外,还可以通过kwargs参数,给view方法指定默认的kwargs参数,还有name参数,用来命名该URL,主要用在URL反解中,至于prefix用处不大,不解释。
url()方法最终构造了一个对象,我们姑且叫它URL映射对象,当第一次访问这个对象去匹配URL时,它会把这个对象中的正则表达式编译一次,然后保存在该对象中,所以以后再次匹配时,就会很快,不会重复编译该正则表达式了。在这里正则匹配其实就是用就是python的re模块,使用过程大致如下:
# 第一次访问时,编译,然后保存在url对象中
regex = re.compile(regex_str, re.UNICODE) # 每次URL访问时,进行正则匹配
match = regex.search(path)
kwargs = match.groupdict()
args = match.groups()
从URL中获取参数,其实是通过re模块中named groups和non-named groups的概念来获取的,通过match.groupdict()得到的是named groups,其实就是一个字典,字典的key是在URL中指定的,该字典会作为kwargs参数传递给view,而通过match.groups()得到的是non-named groups,是一个元组,即tuple,该元组会作为args参数传递给view。不过,这里的args和kwargs是不能够同时存在的,当有kwargs不为空时,args就会被置空,当kwargs为空时,args才会被用到,而传递给view的kwargs就只有url()方法中指定的默认kwargs。也就是说,如果你在URL中使用了named groups,那么non-named groups就会被忽略,如果只使用了non-named groups,它才会被作为args参数,传递给view方法。
解析一下我们上面提到的例子,假如我们有url和view:
urls:
url(r'^articles/(\d{4})/$', 'news.views.year_archive')
url(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive')
views:
def year_archive(request, *args, **kwargs):
pass def month_archive(request, *args, **kwargs):
pass
当我们访问”articles/2014/”这个路径的时候,解析的过程如下:
>>> import re
>>> regex = re.compile(r'^articles/(\d{4})/$', re.UNICODE)
>>> match = regex.search("articles/2014/")
>>> match.groupdict()
{}
>>> match.groups()
('',)
当我们访问”articles/2014/11”这个路径时,解析的过程如下:
>>> import re
>>> regex = re.compile(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', re.UNICODE)
>>> match = regex.search("articles/2014/11/")
>>> match.groupdict()
{'year': '', 'month': ''}
>>> match.groups()
('', '')
所以最终传递给month_archive()方法中的参数应该是这样的:args=(),kwargs = {'month': u'11', 'year': u'2014'}
再罗嗦一句,因为url()可以指定一个kwargs参数,它是该url关联的view()方法的默认kwargs参数,也就是说如果在url()方法中指定了kwargs,那么会将这个参数的内容,也传递到view方法中的kwargs参数中。
好,至此,url()方法基本上就清楚了,第二个问题也解决了,至于name参数,到下面讲到URL反解的时候再详细解释。
patterns()
接下来,我们来看patterns()方法,这个其实比较简单,它就是返回一个由url()方法构造的URL映射对象组成的列表。它有一个必填参数是prefix,这个prefix是它所包含的view的公共前缀,这么做是为了避免代码重复,比如:
urlpatterns = patterns('',
url(r'^articles/(\d{4})/$', 'news.views.year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
可以写成:
urlpatterns = patterns('news.views',
url(r'^articles/(\d{4})/$', 'year_archive'),
url(r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
)
注意,由patterns()生成的列表,被赋值给urlpatterns这个变量,这个变量是不能随便定义的,必须是约定好的,默认django会去URLconf中查找这个变量,也许你可以在某个地方设定一个参数,来换个约定,改变一下这个变量名。
include()
看上面的例子就可以了。
2. URL的反查
如果没有下面这种情况,即同一个urls.py模块被多个域名使用。那在写url时,只要注意两点就可以实现反查。
urlpatterns = patterns('',
url(r'^author-polls/', include('polls.urls', namespace='author-polls', app_name='polls')),
url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls', app_name='polls')),
)
ok,那我们先不考虑上面这种情况,因为出现的概率很小,而且出现了再修改原有的url也可以,影响不大。
如果想对某个url进行反查,那要做两点(其实不是必须,但最好这样做,这样也便于对其它url进行反查,名称空间),
我们把include和name跟文件系统中的目录和文件做比较
1. 该url路径上用到的所有url()方法中必须加name参数,如果url()方法中有include(),那不用加name参数。
name相当于文件,同一目录下的文件不能重名,即任何一个patterns(),它里面的各个url()的name参数不能相同。
2. 该url路径上用到的所有include()方法中必须namespace参数。
include相当于目录,同一父目录下的目录不能重名,即任何一个patterns(),它里面的各个url()中的include()的namespace不能重名
当每个url都这样做时,就可以保证每个url在命名空间中可以唯一定位到。见下面例子
urls.py
from django.conf.urls import include, url, patterns
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace='polls')),
)
polls/urls.py
from django.conf.urls import url, patterns from . import views urlpatterns = patterns(
url(r'^$', views.IndexView.as_view(), name='index')/,
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
)
在python代码中,用下面的代码就能得到该url的path='/polls/index/',即相对于域名的路径。
include()方法是可以嵌套的,用类似reverse('polls:author_polls:index')可以得到路径
reverse('polls:index')
在模板中,用下面的代码获取
{% url 'polls:index' %}
参考:
http://blog.csdn.net/hackerain/article/details/40701099
http://python.usyiyi.cn/django/topics/http/urls.html
Django中URL的解析和反查的更多相关文章
- Django之url反向解析
在urls.py文件中,在进行url映射时,为请求的url命个名,以便在模板页面或者views.py视图中可以进行反向解析,同时在修改了url映射的请求路径,名称不变的情况下,不再修改模板页面或者视图 ...
- Django中url匹配规则的补充
Django中url匹配规则是在urls.py文件中配置的. 1.关于正则匹配优先级 在url匹配列表中,如果第一条和第二条同时满足匹配规则,则优先匹配第一条. 在url匹配列表中,如果第一条为正则模 ...
- django中url路由配置及渲染方式
今天我们学习如何配置url.如何传参.如何命名.以及渲染的方式,内容大致有以下几个方面. 创建视图函数并访问 创建app django中url规则 捕获参数 路径转换器 正则表达式 额外参数 渲染方式 ...
- django中url 和 path 的区别
django中 url 和 path 都是配置路径,有什么不同? django.urls path django.conf.urls url path 与 url 是两个不同的模块,效果都是响应返回 ...
- django 中url与path小记
1. 在django 2.0中增加了一些新的特性 更简单的URL路由语法 (Simplified URL routing syntax) admin应用的针对移动设备的优化改进(Mobile-frie ...
- Django——URL详解/Django中URL是如何与urls文件匹配的
URL标准语法 protocol://hostname[:port]/path/[:parameters][?query]#fragment https://i.cnblogs.com/EditPos ...
- django的url反向解析
目的:防止页面中url地址改变,其他与这个URL地址有关联的都要改,减少耦合度 使用:主要分为在html中和视图函数中的使用 HTML中的使用: 如果我们在项目的url文件中通过include导入了应 ...
- Django中url的反向查询
明确几个概念: application namespace: 正在部署的app的名称,一个app的多个实例应该具有相同的application namespace. 可以通过在URLconf模 ...
- Django学习笔记之Django的url反向解析
0x00 URL反向解析和三种不同的反向解析方式 Django中提供了关于URL的映射的解决方案,可以做两个方向的使用: 1.普通解析过程:由客户端的浏览器发起一个url请求,Django根据URL解 ...
随机推荐
- jquery-包裹元素
1.wrap方法 在每个匹配的元素外层包上一个html元素 参数类型说明: 1)html字符串 $('p').wrap('<div></div>'); 传入的html标签也可以 ...
- jQuery操作属性和样式详解
我们可以使用 javascript 中的getAttribute和setAttribute来操作元素的"元素属性".在 jQuery 中给你提供了attr()包装集函数, 能够同时 ...
- 关于NaN(Not a Number)的问题
在游戏运行时,代码若写得不安全很容易出现NAN的异常.一旦NAN出现整个游戏不崩溃也坏死掉了,游戏上了则是要被直接打回来的节奏,更是一个开发及测试人员每人都要扣3000块的大BUG. 一般表现为: ...
- android SDK manager 快速更新【转】
- Cookie示例
//caozuocookie var webusername = ""; function getCookie(name){ var arr,reg=n ...
- windows下dubbo-admin和zookeeper安装部署
1. 概述 ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂 ...
- Post方式调用wcf服务
我们平常在PC端调用WCF服务,只要知道WCF服务的地址,客户端直接添加引用服务就可以使用了,殊不知还有其他方式,其实,我们也可以 通过HTTP POST的方式调用WCF服务,这样就不用添加引用了,在 ...
- oracle函数学习_根据用户id获取用户角色
create or replace function FN_GET_ROLES(v_user_id varchar2) return varchar2 istype zy_emp_cursor is ...
- HTML的设计与应用
<html> <head><!-- 设置网页头标题--> <!-- 不需要在页面中显示的内容写在这个里面 --> <base href=" ...
- GIS-010-ArcGIS JS 三种查询模式(转)
QueryTask.FindTask.IdentifyTask都是继承自ESRI.ArcGIS.Client.Tasks: 1.QueryTask:是一个进行空间和属性查询的功能类,它可以在某个地图服 ...