Code前端首页关于Code前端联系我们

Django 如何处理 URL 请求

terry 2年前 (2023-09-24) 阅读数 68 #后端开发

当用户请求 Django 站点上的页面时,Django 使用以下算法来决定运行哪个 Python 代码:
1Django 确定 URLconf 根模块的使用:通常,这是设置值ROOT_URLCONF,但如果传入的HttpRequest对象具有urlconf属性(通过中间件设置),则使用它的值而不是设置ROOT_URLCONF
​​ ​​​​2Django加载Python模块并查找可用的URL模式;它是 django.urls .path() 和/或 django.urls.re_path() 实例的列表
3Django 将按顺序迭代每个 url 模式,并在请求的 url 与第一个模式匹配并匹配 path_info 时停止
4 一旦 URL 成功匹配,Djagno 就会导入并调用适当的视图。视图可以是 Python 函数(或基于类的视图)。该视图采用以下参数:
○HttpRequest 序列
○如果匹配的 URL 包含未命名组,则将提供正则表达式匹配作为位置参数
○ 关键字参数由与路径表达式并传递给 django.urls.path() 或 django.urls.re_path() 的可选 kwargs 参数中给出的任何参数都将覆盖
5 如果没有找到 URL 或在匹配过程中发生异常,Django 将调用相应的错误处理视图

Simple URLconf

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),
]

注意:
●使用尖括号从 URL 中获取值
●捕获的值可以选择包含转换器类型。例如,使用 捕获整数参数。如果不包含转换器将匹配除 /
之外的任何字符 ●无需添加正向反斜杠,因为每个 URL 都有它,例如它应该是articles 而不是 /articles

一些示例请求
●/articles /2005 /03/将匹配列表中的第三个URL,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/ 将匹配 URL 列表中的最后一项 Django 将调用views.article_detail(request,year=2003,month=3,slug="building-a-django-site")

Path Converter
●str - 匹配除“/”之外的非空字符串 由数字、-、_ 组成的短标记,例如 build-your-1st-django-site
uuid - 匹配格式化的 UUID。必须包含连字符和所有字符,以防止多个 URL 映射到同一页面。对于小写字母,例如075194d3-6885-417e-a8a8-6c931e272f00,函数参数获取实例UUID
●path - 匹配非空字段,包括路径分隔符“/”,允许您匹配完整的URL Path而不是 URL Part Match as str

注册您自己的路径转换器
转换器是一个包含以下内容的类:

正则表达式类属性
字符串形式的正则表达式类属性

class FourDigitYearConverter:    regex = '[0-9]{4}'
    def to_python(self, value):        return int(value)
    def to_url(self, value):        return '%04d' % value

方法 to_python (self, value)
●用于处理将匹配的字符串转换为传递给函数的类型
●如果没有转换为给定值,则应抛出 ValueError
●ValueError 指示no match Success ,因此如果另一个 URL 模式未成功匹配,则返回 404

to_url(self, value) 方法
●处理Python类型到字符串的转换,以便在URL中使用
●如果给定的值无法转换,它应该引发ValueError
●ValueError被解释为不匹配,因此reverse()将引发NoReverseMatch,除非有其他匹配的 URL 模式

class FourDigitYearConverter:    regex = '[0-9]{4}'
    def to_python(self, value):        return int(value)
    def to_url(self, value):        return '%04d' % value

在 URLconf 中使用 register_converter() 注册自己的转换器类:

from django.urls import path, register_converter
from . import converters, views
register_converter(converters.FourDigitYearConverter, 'yyyy')
urlpatterns = [    path('articles/2003/', views.special_case_2003),    path('articles/<yyyy:year>/', views.year_archive),    ...]

使用正则表达式
●如果路径和转换器语法不能很好地定义 URL 模式,您可以使用正则表达式
●必须使用re_path()而不是path()
●在Python正则表达式中,命名正则表达式组的语法是(?Ppattern),其中name是组的名称,pattern是模式匹配

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),]

这实现了与上一个示例大致相同的功能,除了:
●将匹配的 URL 将受到轻微限制,例如 10,000 年将不匹配,因为一年的长度有限为 4
●无论正则表达式匹配什么,每个捕获的参数都会以字符串类型发送到显示器

使用未命名的正则表达式组
●命名组语法,例如(? P[0-9]{4})
●更短的未命名组,例如 ([0-9]{4})
不建议使用此用法,因为这样更容易比较卷预期含义与显示参数之间存在误差。无论如何,建议在给定的正则表达式中仅使用一种样式
混合两种样式时,所有未命名的组都会被忽略,只有命名的组将被传递到显示函数
如果匹配的 URL 包含未命名的组组,然后正则表达式中的匹配项将作为位置参数提供

性能
urlpatterns 中的每个正则表达式都会在第一次访问时编译,使系统速度相当快

URLconf 查找什么
请求的 URL被视为常规 Python 字符串
URLconf 在找到匹配项时进行搜索和匹配 不包含 GET 或 POST 请求方法参数和域名

https://www .example.com/myapp/ 在请求中, URLconf 将搜索 myapp/
在对 https://www.example.com/myapp/?page=3 的请求中,URLconf 仍会查找 myapp/
URLconf 不会检查使用了哪种请求方法;换句话说,所有的请求方法 - 即无论是同一个 URL 的 POST 请求、GET 请求还是 HEAD 请求方法等 - 都会被路由到同一个函数

提供默认的视图参数

# URLconffrom 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.    ...

包含附加 URLconfs
两者 每个 URL 模式都指向相同的视图。页面视图功能
第一个模式无法捕获 URL 中的任何内容。如果第一个 url 模式与 url 匹配,page() 将使用其默认参数 num= 1
第二个 url 模式与 url 匹配,page() 将使用捕获的任何 num

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门