路由简单配置二:名称空间、path方法
2.url控制器-path方法
思考如下:
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),
]
第一个问题,函数 year_archive 中year参数是字符串类型的,因此需要先转化为整数类型的变量值,当然year=int(year) 不会有诸如如TypeError或者ValueError的异常。那么有没有一种方法,在url中,使得这一转化步骤可以由Django自动完成?
第二个问题,三个路由中article_id都是同样的正则表达式,但是你需要写三遍,当之后article_id规则改变后,需要同时修改三处代码,那么有没有一种方法,只需修改一处即可?
在Django2.0中,可以使用 path 解决以上的两个问题。
re_path与django 1.0的url的用法是完全一样的,在使用1.0版本的时候换成url就可以了!
django 2.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的使用规则
- 使用尖括号(<>)从url中捕获值。
- 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。
- 无需添加前导斜杠。
示例分析表
python转换器
Django默认支持以下5个转化器:
- str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
- int,匹配正整数,包含0。
- slug,匹配字母、数字以及横杠、下划线组成的字符串。
- uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path,匹配任何非空字符串(?除开,?是分割url和get请求数据的),包含了路径分隔符
注册自定义转换器
对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:
- regex 类属性,字符串类型
- to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
- to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
首先:创建一个app01/urlconvert.py文件为例,自定义一个类,如下
# 自定义转换器,首先自己定义一个接口的类
class MonConvert:
regex = "[0-9]{2}"
# regex是匹配规则,必须写成regex变量
def to_python(self, value):
return int(value)
def to_url(self,value): # 反向解析 后面后将讲到
return "%04d" % value
然后再以first_pro/url为例进行注册
from django.urls import path,re_path,include,register_converter
from app01 import views
from app01.urlconvert import MonConvert # 导入自己写的一个类
# register_converter 注册转换器用的,这里来注册自定义类,并且取名字为"mm"
register_converter(MonConvert, "mm")
urlpatterns = [
# 自定义转换器
path("articles/<mm:month>",views.path_month)
]
app01/views.py对应的代码
from django.shortcuts import HttpResponse
# path的自定义转换器
def path_month(request,month):
print(month,type(month))
return HttpResponse('自定义path转换器')