美文网首页
Django路由系统

Django路由系统

作者: 漓江塔塔主 | 来源:发表于2018-09-26 10:58 被阅读0次

    python django官方文档地址:https://docs.djangoproject.com/zh-hans/2.1/topics/http/urls/
    非常惭愧,之前还不知道看官方文档,所以这篇文章就主要是参考的官方文档url这块的文章

    URL调度器
    对于高质量的Web 应用来说,使用简洁、优雅的URL 模式是一个非常值得重视的细节。Django 允许你自由地设计你的URL,不受框架束缚。

    首先先来了解一下Django如何处理一个请求:

    • Django确定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但如果传入 HttpRequest对象具有urlconf 属性(由中间件设置),则将使用其值代替 ROOT_URLCONF设置。
    • Django加载Python模块并查找变量 urlpatterns。这应该是Python列表django.urls.path() 和/或django.urls.re_path()实例。
    • Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来。
      一旦其中一个URL模式匹配,Django就会导入并调用给定的视图,这是一个简单的Python函数(或基于类的视图)。视图传递以下参数:
      *一个HttpRequest实例。
      *如果匹配的URL模式未返回任何命名组,则来自正则表达式的匹配将作为位置参数提供。
      关键字参数由路径表达式匹配的任何命名部分组成,由或者 可选kwargs参数中指定的任何参数覆盖 。 如果没有URL模式匹配,或者在此过程中的任何点期间引发异常,Django将调用适当的错误处理视图。

    URL的正向解析

    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('articles/<int:year>/', views.year_archive),
        path('articles/<int:year>/<int:month>/', views.month_archive),
        path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
    ]
    

    就直接用官方文档的示例代码了,非常简洁
    首先第一行导入path模块,然后在第二行导入视图模块,视图模块应该在接下来我会写一篇博客来详细阐述,当下的重点还是urlpatterns。
    按照上面的步骤,默认加载的当前模块,此时django就开始匹配,首先要明确的一点就是,django是按照从上到下的顺序来匹配的,一旦匹配上其中一条,下面的就不会在执行,所以在写网页框架是应当注意写的顺序。
    注意代码中的尖括号,在Django中尖括号的作用是捕获值,:之前式转换器的类型,后面是转换器捕获值的名称。此处应当提前说明一下,此处捕获的参数会被传入对应的views函数里面,假使函数没有声名这个参数,就会报错。

    视图指定参数的默认值

    有一个方便的小技巧是指定视图参数的默认值。下面是一个URLconf和视图的示例:

    URLconf
    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        path('blog/', views.page),
        path('blog/page<int:num>/', views.page),
    ]
    
    # View (in blog/views.py)
    def page(request, num=1):
        # Output the appropriate page of blog entries, according to num.
        ...
    

    在上面的示例中,两个URL模式都指向同一个视图 views.page- 但第一个模式不会从URL捕获任何内容。如果第一个模式匹配,该page()函数将使用它的默认参数num,也就是1。如果第二个模式匹配, page()将使用num捕获的任何值。

    来看几个例子

    • 请求/articles/2005/03/与列表中的第三个条目匹配。Django会调用该函数 ,函数就是views.month_archive(request, year=2005, month=3)
    • /articles/2003/将匹配列表中的第一个模式,而不是第二个模式,因为模式是按顺序测试的,第一个是第一个要通过的测试。随意利用订单插入这样的特殊情况。在这里,Django会调用该函数 views.special_case_2003(request)
    • /articles/2003 不匹配任何这些模式,因为每个模式都要求URL以斜杠结尾。
    • /articles/2003/03/building-a-django-site/将匹配最终模式。Django会调用该函数 。views.article_detail(request, year=2003, month=3, slug="building-a-django-site")

    路径转换器

    默认情况下,以下路径转换器可用:
    str- 匹配除路径分隔符之外的任何非空字符串'/'。如果转换器未包含在表达式中,则这是默认值。
    int - 匹配零或任何正整数。返回一个int。
    slug - 匹配由ASCII字母或数字组成的任何slug字符串,以及连字符和下划线字符。例如, building-your-1st-django-site。
    uuid - 匹配格式化的UUID。要防止多个URL映射到同一页面,必须包含短划线并且字母必须为小写。例如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID实例。
    path- 匹配任何非空字符串,包括路径分隔符 '/'。这使您可以匹配完整的URL路径,而不仅仅是URL路径的一部分str。
    此外还有注册自定义转换器的操作,但是由于有正则表达式匹配的缘故,我觉得在这就先不赘述了

    使用正则表达式

    如果路径和转换器语法不足以定义URL模式,则还可以使用正则表达式。为此,请使用 re_path()而不是path()。
    在Python正则表达式中,命名正则表达式组的语法是(?P<name>pattern),name是匹配的字符串的名称,并且 pattern是要匹配的模式。
    对前面的示例URLconf使用正则表达式重写:

    from django.urls import path, re_path
    
    from . import views
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
        re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
        re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
    ]
    

    这完成了与前一个示例大致相同的事情,除了:

    • 匹配的确切网址稍微受限制。例如,年份10000将不再匹配,因为年份整数被限制为恰好四位数。
    • 无论正则表达式匹配什么类型,每个捕获的参数都将作为字符串发送到视图。

    使用未命名的正则表达式组

    除了命名组语法之外,例如(?P<year>[0-9]{4}),您还可以使用较短的未命名组,例如([0-9]{4})。
    不特别推荐这种用法,因为它更容易在匹配的预期含义和视图的参数之间意外引入错误。

    include的用法

    在一般情况下,进行网站的编写,url不可能简简单单的只有几个,而应该是很多,此时如果将需要匹配的url全部放到urlpattern里面,肯那个就就会显得有些冗余。include函数就应运而生了。每当Django遇到时include(),它都会删除与该点匹配的URL的任何部分,并将剩余的字符串发送到包含的URLconf以进行进一步处理。

    被包含的URLconf会收到来自父URLconf捕获的任何参数##

    from django.urls import include, path
    
    urlpatterns = [
        # ... snip ...
        path('community/', include('aggregator.urls')),
        path('contact/', include('contact.urls')),
        # ... snip ...
    ]
    

    上面的url,community/就会跳转到aggregator.urls内部进行继续匹配
    下面的这种写法也是被允许的

    from django.urls import include, path
    from . import views
    
    urlpatterns = [
        path('<page_slug>-<page_id>/', include([
            path('history/', views.history),
            path('edit/', views.edit),
            path('discuss/', views.discuss),
            path('permissions/', views.permissions),
        ])),
    ]
    

    传递额外选项

    URLconfs允许您将额外的参数作为Python字典传递给视图函数。
    该path()函数可以采用可选的第三个参数,该参数应该是传递给视图函数的额外关键字参数的字典。
    例如:

    from django.urls import path
    from . import views
    urlpatterns = [
        path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}),
    ]
    

    在这个例子中,对于请求/blog/2005/,Django将调用 。views.year_archive(request, year=2005, foo='bar')
    同样,您可以传递额外的选项,include()并且包含的​​URLconf中的每一行都将传递额外的选项。无论是传递给当前的url文件还是include指向的文件,都是被允许的

    URL的反向解析

    相关文章

      网友评论

          本文标题:Django路由系统

          本文链接:https://www.haomeiwen.com/subject/vxufoftx.html