前言:
以下内容参考官网文档,学习整理。慢慢完善,希望对你有帮助。暂时只是把官网翻译了一下。
问题:当一个用户请求Django 站点的一个页面,下面是Django 系统决定执行哪个Python 代码使用的算法?
第一步:Django决定要使用的根URLconf模块,通常这个值是由ROOT_URLCONF设置的。但是,如果传入的HttpRequest对象具有urlconf属性(由中间件设置),那么它的值将用于替代ROOT_URLCONF设置。
第二步:Django加载Python模块并查找参数 urlpatterns ,这应该是django.urls.path()和django.urls.re_path() 实例的Python列表
第三步:Django依次匹配每个URL模式,在与请求的URL匹配的第一个模式停下来。
第四步:当其中一个URL模式匹配,Django将导入并调用对应的视图,这些视图是一个简单的Python函数(或基于类的视图)。视图被传递一下参数:
-
一个 HttpRequest 实例。
-
如果匹配的URL模式没有返回指定的组,那么正则表达式中的匹配将作为位置参数提供。
-
关键字参数由路径表达式匹配的任何命名部分组成,被django.urls.path() 或 django.urls.re_path()的可选kwargs参数中指定的任何参数覆盖。
第五步:如果没有匹配的URL模式,或者在此过程中的任何一点上出现异常,Django将调用一个适当的错误处理视图。请参考下面的错误处理.
下面是一个简单的 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中获取参数,需要使用尖括号(<>)。
-
如果获取参数可以包含转换类型,比如,使用<int:name>来获取整型参数,如果不包含转换类型,则匹配除一个字符’/‘之外的任意字符串。
-
不需要以 / 字符(前斜杠)开头,因为每一个URL都有。例如,是 articles 开头,而不是 /articles 开头。
一些请求例子:
-
'/articles/2005/03/' 将匹配列表中的第3个。Django将调研函数方法 views.month_archive(request, year=2005, month=3)
-
‘/articles/2003/’ 将匹配列表中的第1个。而不是第2个,因为匹配是按照顺序进行的,并且第1个是匹配的。当然你也可以自由控制这个顺序,或者插入一些其他的匹配模式。Django会调用对应函数方法,比如这里的views.special_case_2003(request)
-
‘/articles/2003’将无法匹配列表中的任何一个模式。因为每一个模式都是以/ 字符(前斜杠)结束的。
-
‘/articles/2003/03/building-a-django-site/‘ 将匹配列表中的最后一个。Django将调用函数方法views.article_detail(request, year=2005, month=03, slug=“building-a-django-site")
路径转换类型
A、路径转换默认可以使用以下类型:
-
str - 匹配除路径分隔符'/'之外的任何非空字符串。如果表达式中没有包含转换类型,默认为str类型。
-
int - 匹配零或任何正整数。返回一个int型。
-
slug - 匹配任何由ASCII字母或数字组成的slug字符串,加上连字符和下划线字符。例如,building-your-1st-django-site。(更多slug使用说明:https://blog.youkuaiyun.com/lx_9986/article/details/8511937)
-
uuid - 匹配格式化的uuid。为了防止多个url映射到同一个页面,必须包含’-‘和小写字母。例如:075194d3-6885-417e-a8a8-6c931e272f00,返回一个uuid。
-
path - 匹配包含路径分隔符’/‘的任何非空字符串。可以是完整的路径。
B、自定义路径转换类型。对于更复杂的匹配需求,可以定义自己的路径转换类型,一个转换类型是一个类,包含如下:
-
一个 regex (正则表达式)类属性。以字符串的形式。
-
一个 to_python(self, value) 函数方法。它处理将匹配的字符串转换为应该传递给视图函数的类型。如果不能转换给定的值,它应该会引发ValueError 的异常错误。
-
一个 to_url(self, value) 函数方法。它处理将Python类型转换为URL中使用的字符串。
在converters.py中定义如下,例如:
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
在urls.py中使用register_converter()函数方法,在你的 URLconf 中注册自定义转换器类,例如:
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),
...
]
使用正则表达式
未完待续...