django 路由层
1. django2.x 版本的path
1. 基本用法
django2.0的re_path和1.0的url一样
urlpatterns = [
re_path('articles/(?P<year>[0-9]{4})/', year_archive),
re_path('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),
re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),
re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),
]
# 考虑下面两个问题:
1. 函数 year_archive 中year参数是字符串类型的,因此需要先转化为整数类型的变量值
当然year=int(year) 不会有诸如如TypeError或者ValueError的异常。
那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成?
2. 三个路由中article_id都是同样的正则表达式,但是你需要写三遍
当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可?
# 在Django2.0中,可以使用 path 解决以上的两个问题
# 示例
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>/', views.article_detail),
# path才支持,re_path不支持
path('order/<int:year>',views.order),
]
# 基本规则
1. 使用尖括号(<>)从url中捕获值
2. 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量
若果没有转化器,将匹配任何字符串,当然也包括了 / 字符
3. 无需添加前导斜杠
示例分析表
2. path转化器
Django默认支持以下5个转化器:
- str, 匹配除了路径分隔符(
/
)之外的非空字符串,这是默认的形式 - int, 匹配正整数,包含0。
- slug, 匹配字母、数字以及横杠、下划线组成的字符串。
- uuid, 匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
- path, 匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
1. 例子
path('login/<int:year>', views.login),
path('login/<str:year>', views.login),
path('login/<path:p>', views.article),
2. 高级例子
# 实现匹配这种路径:http://127.0.0.1:8000/liuqingzheng/p/4444.html
path('<str:name>/p/<int:id>.html', views.article),
re_path(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login),
url(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login), # url在2.x以后不建议使用
3. 转换器可以不可以在re_path中使用
3. 注册自定义转化器
对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:
-
regex
类属性,字符串类型 -
to_python(self, value)
方法,value是由类属性regex
所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。 -
to_url(self, value)
方法,和to_python
相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
示例
1. 写一个类
regex属性:这里写的正则表达式就能匹配
to_python 方法
to_url 方法
2. 注册这个类
register_converter(类名, 'lqz')
3. 在path中使用
path('<lqz:name>/', views.article),
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
# 使用register_converter将其注册到URL配置中:
from django.urls import register_converter, path
from . import converters, views
register_converter(converters.FourDigitYearConverter, 'myconverter')
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<myconverter:year>/', views.year_archive),
...
]
4. django版本区别
# 区别1
django1.X路由层使用的是url方法
url()第一个参数支持正则
django2.X 3.X版本中路由层使用的是path方法
path()第一个参数是不支持正则的(精准匹配)
# 2.X和3.X里面的re_path就等价于1.X里面的url
# 如果不习惯使用path django提供了另外一个方法
from django.urls import path, re_path
re_path