Django路由系统

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的反向解析

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容