加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Python探索之URL Dispatcher实例分析

发布时间:2022-07-02 17:19:55 所属栏目:PHP教程 来源:互联网
导读:URL dispatcher简单点理解就是根据URL,将请求分发到相应的方法中去处理,它是对URL和View的一个映射,它的实现其实也很简单,就是一个正则匹配的过程,事先定义好正则表达式和该正则表达式对应的view方法,如果请求的URL符合这个正则表达式,那么就分发这个
  URL dispatcher简单点理解就是根据URL,将请求分发到相应的方法中去处理,它是对URL和View的一个映射,它的实现其实也很简单,就是一个正则匹配的过程,事先定义好正则表达式和该正则表达式对应的view方法,如果请求的URL符合这个正则表达式,那么就分发这个请求到这个view方法中。
 
  有了这个base,我们先抛出几个问题,提前思考一下:
 
  好,先来看一个简单的例子:
 
  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的例子,它在一个单独的python模块定义,Django中管这个模块叫做URLconf,其实,就是通过python代码方式实现的配置文件,在这个配置中定义了URL路径和对应的处理方法之间的映射。在Django中,是通过“树”的结构来管理URLconf之间的关系的,在Django中的主配置文件中,有一个叫做ROOT_URL_CONF的配置项,就是用来指定根URLconf,从根URLconf开始,逐条进行匹配,直到找到匹配项为止,这就是我们上面提到的第一个问题的答案,下面还会再仔细剖析。
 
  在上面例子中,我们可以看到有3个方法:patterns, url, include。url方法构建了一个URL到View方法的映射关系对象,patterns将这些映射关系对象组织成为一个python的列表,那include是做什么的呢?它就是我们上面说到的“树”结构关系的联系者,include会关联其他的URLconf到本URLconf,也就是说include关联的是孩子节点。整个URL dispatcher体系,就是由这三个方法构建起来的,下面我们重点来介绍这三个方法,了解了这三个方法,整个URL映射机制就会非常清楚了。
 
  def patterns(prefix, *args):
    pass
  def url(regex, view, kwargs=None, name=None, prefix=''):
    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和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()
  ('2014',)
  所以最终传递给year_archive()方法中的参数应该是这样的:
 
  (Pdb) pp args
  (u'2014',)
  (Pdb) pp kwargs
  {}
  当我们访问”articles/2014/11”这个路径时,解析的过程如下:
 
  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中查找这个变量,也许你可以在某个地方设定一个参数,来换个约定,改变一下这个变量名。
 
  在2.0版本的Django中,会舍弃这个方法,而是直接赋值给urlpatterns一个列表,不做过多讨论。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读