zoukankan      html  css  js  c++  java
  • 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()

    #django.conf.urls.defaults.patterns()
    django.conf.urls.defaults import *  #  import 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()

    语法:

    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输入框中输入 http://127.0.0.1:8000/blog/index/ 则,它会截取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中的 每一个 视图函数。

    那么在浏览器输入:http://127.0.0.1:8000/BeginMan/blog/other/

    则输出: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)) 

    输入:http://127.0.0.1:8000/blog/BeginMan/20/index/

    输出:ok:BeginMan,20

    注意 后面不要忘了去匹配blog urls的哪个urls。如(r'^index/$’)

    url高级配置

    参考:Django零碎知识(10):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'),    #命名组

    则输入地址:http://127.0.0.1:8000/position/2013/15/http://127.0.0.1:8000/name/2013/15/在相应视图函数中进行处理

    #以位置参数的形式,如果位置改变,如(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))

    则输入:http://127.0.0.1:8000/bar/http://127.0.0.1:8000/foo/ 则输出: bar、 foo

    常见应用是传递模板:

    # urls.py
    
    from django.conf.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
    from mysite.models 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})
  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/bigtreei/p/8564218.html
Copyright © 2011-2022 走看看