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解 ...
随机推荐
- linux,ubuntu14.04.5下安装搜狗输入法
参考内容: http://www.linuxidc.com/Linux/2015-03/114347.htm https://jingyan.baidu.com/album/ad310e80ae6d9 ...
- jQuery-处理class属性
1.addClass方法 为每个匹配的元素添加指定的样式类名 参数类型说明: 1)class名称(字符串) 每个匹配元素添加的一个或多个用空格隔开的样式名 2)function(index, curr ...
- Oracle中查询主键、外键、sequence、表基本信息等
一次看到某张表中有几条ID相同的数据,通过业务确认该ID应该是唯一的,后来找到原因,因为DBA未对该表建主键. 现在DBA工作比较忙,我们项目有时需要新增或者修改数据库表结构时,可能需要对表结构进行确 ...
- mysql中" ' "和 " ` "的区别
http://blog.csdn.net/yang3290325/article/details/3349907
- Css中position、float和clear整理
Position: absolute 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位. 元素的位置通过 "left", "top", ...
- oracle_存储过程_没有参数_更新过期申请单以及写日志事务回滚
CREATE OR REPLACE PROCEDURE A_MEAS_MIINSP_PLAN_UPDATEASvs_msg VARCHAR2(4000);log_body VARCHAR2(400); ...
- swift--控件工厂类的实现
控件工厂类,简而言之就是,减少代码的复用率,只在哪里用,然后在哪里调: 代码如下: import UIKit class ViewFactory: UIView,UITextFieldDelegate ...
- 查询软件和硬件列表清单[将文章里代码另存为 list.vbs,双击运行就会出现一个html页面]
'==========================================================================' Name: 查询软件和硬件列表清单' 不支持W ...
- HTML5怎么实现录音和播放功能
小旋风柴进 html: [html] view plain copy <span style="white-space:pre"> </span><a ...
- 数据提交方式:post和get
众所周知,在B/S应用程序中,前台与后台的数据交互,都是通过HTML中Form表单完成的.而Form提供了两种数据传输的方式——get和post. Get请求表示客户端请求一个ur ...