• 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})
  • 相关阅读:
    char 型变量中能不能存贮一个中文汉字,为什么?
    抽象类(abstract class)和接口(interface)有什么异同?
    描述一下JVM加载class文件的原理机制?
    重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
    String和StringBuilder、StringBuffer的区别?
    此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    是否可以继承String类?
    两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
    laraval join 的理解
    whereHasIn方法
  • 原文地址:https://www.cnblogs.com/bigtreei/p/8564218.html
Copyright © 2020-2023  润新知