摘要
Django提供了许多内置的路径转换器,但有时候它们并不能满足我们的需求。不要担心,我们可以自定义自己的转换器!在此之前,让我们先来看看Django内置的转换器,它们是多么的强大和神奇。
正文
Django(6)自定义路由转换器
自定义路径转换器
有时候上面的内置的url转换器并不能满足我们的需求,因此django给我们提供了一个接口可以让我们自己定义自己的url转换器
django内置的路径转换器源码解析
在我们自定义路由转换器之前,我们先查看一下django内置的那些路由转换器怎么写的,源码路径from django.urls import converters
class IntConverter:
regex = '[0-9]+'
def to_python(self, value):
return int(value)
def to_url(self, value):
return str(value)
class StringConverter:
regex = '[^/]+'
def to_python(self, value):
return value
def to_url(self, value):
return value
class UUIDConverter:
regex = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
def to_python(self, value):
return uuid.UUID(value)
def to_url(self, value):
return str(value)
class SlugConverter(StringConverter):
regex = '[-a-zA-Z0-9_]+'
class PathConverter(StringConverter):
regex = '.+'
DEFAULT_CONVERTERS = {
'int': IntConverter(),
'path': PathConverter(),
'slug': SlugConverter(),
'str': StringConverter(),
'uuid': UUIDConverter(),
}
REGISTERED_CONVERTERS = {}
def register_converter(converter, type_name):
REGISTERED_CONVERTERS[type_name] = converter()
get_converters.cache_clear()
从上面我们可以非常分析的看到,django内置的路径转换器是先定义了一个类,类中定义了一个类属性regex
作为正则表达式的值,然后定义了2个方法to_python
和to_url
,最后定义了一个register_converter
函数,将路径转换器注册到django中去
我们这里给他划分为5步:
- 1.创建一个
converters.py
,在文件中定义一个类。 - 2.在类中定义一个属性
regex
,这个属性是用来保存url转换器规则的正则表达式。 - 3.实现
to_python(self,value)
方法,这个方法是将url中的值转换一下,然后传给视图函数的。 - 4.实现
to_url(self,value)
方法,这个方法是在做url反转的时候,将传进来的参数转换后拼接成一个正确的url。 - 5.将定义好的转换器,注册到django中。
小案例
接下来我们自己定义一个转换器,满足4位数字的路径匹配
新建一个converters.py文件,代码如下:
class FourDigitYearConverter:
# 定义正则表达式
regex = '[0-9]{4}'
def to_python(self, value):
return value
def to_url(self, value):
return '%04d' % value
在urls.py
文件下注册自定义的转换器
from django.urls import path, converters
# 注册自定义转换器
register_converter(converters.FourDigitYearConverter, 'yyyy') # yyyy是自定义转换器的类型名称
urlpatterns = [
path('articles/<yyyy:year>', views.articles_yyyy),
]
这样我们就可以匹配4位数字的url地址了
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
温馨提示:如果您访问和下载本站资源,表示您已同意只将下载文件用于研究、学习而非其他用途。
评论0