urls参数转换器
- 用于限制参数
from django.urls import converters
查看converters默认的参数转换器
DEFAULT_CONVERTERS = {
'int': IntConverter(),
'path': PathConverter(),
'slug': SlugConverter(),
'str': StringConverter(),
'uuid': UUIDConverter(),
}
各个值对应的类 ```python class IntConverter: regex = ‘[0-9]+’ #多个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}’
#import uuid uuid.uuid4()这个函数返回的字符串类型
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]+’ #返回-或者a到z或者A-Z或者0到0或
class PathConverter(StringConverter): regex = ‘.+’ #都可以
- 用法
```python
# urls.py
# 参数转换器
path('app/converter/<int:param>', v.url_converter)
# path('app/converter/<str:param>', v.url_converter)
# path('app/converter/<uuid:param>', v.url_converter)
# path('app/converter/<path:param>', v.url_converter)
# path('app/converter/<slug:param>', v.url_converter)
# views.py
def url_converter(request, param):
return HttpResponse("返回值是: {}".format(param))
to_python和to_url
- 在
path()
中使用了<int:param>
后,参数转换器会将这个param传给to_python,返回的是转换后的param。 - 在使用
reverse(view_name,kwarsg)
的时候,kwargs也会调用相应参数转换器,将kwargs的值传给to_url转换为字符串,添加进view_name对应的URL中的参数
自定义URL转换器
- django内置的url转换器不足以满足需求,可以自定义url参数转换器。
- 步骤
- 定义一个类,直接继承自object
- 参考
converters.py
里类的结构。- 定义一个属性regex,这个属性是用来限制url转换器规则的正则表达式
- 实现
to_python(self,value)
,将URL参数的值转换,再传给视图函数 - 实现
to_url(self,value)
,在做URL反转的时候,将传进来的参数转换回原来的参数类型,然后拼接成一个正确的URL
- 将定义好的转换器,使用
django.urls.converters.register_converter
方法注册进Django中
- 例子
- 需求:
- 实现一个获取文章列表的demo,用户可以根据
/articles/文章分类/
的方式来获取文章。其中文字分类的格式是分类1+分类2+分类3
的方式拼接。如果只有一个分类,无需+
- 在
文章分类
参数传到视图函数之前要把这些分类分开存储到list
中。比如参数是book1+book2
,那么传到视图函数的时候就要编程['book1', 'book2']
- 在使用reverse反转的时候,限制传递
文字分类
的参数应该是一个列表,并且要将这个列表变成book1+book2
类型
- 实现一个获取文章列表的demo,用户可以根据
- 实现:
- 需求:
urlpatterns = [
# ()表示一个整体
# ?P<param_name>后面接对这个pram_name的格式描述
# \w 表示0-9,a-z,A-Z,_
# + 表示0个或多个
# \+ 表示纯粹的+,就是+的转义
re_path(r'article/(?P<book_name>\w+|(\w+\+\w+)+)/', v.book_list, name="book_page")
]
```python
# views.py
from django.shortcuts import render, HttpResponse
from django.urls import reverse
def book_list(request, book_name):
target_url = reverse("book_page", kwargs={"book_name": "book1+book2"})
# 默认参数传递是str
return HttpResponse("book_name is: {0} ,target_url is: {1}".format(book_name, target_url))
- 运行
1. 更改
# app中的 converters.py(自己新建)
# 然后在app中的 __init__.py中 from * inport converters
from django.urls import register_converter
class BookType(object):
regex = "\w+|(\w+\+\w+)+" #对参数的判别
def to_python(self, value): #path中使用的时候会将参数转化为list
# 将"book1+book2"转换为["book1", "book2"]
book_list = value.split("+")
return book_list
def to_url(self, value):
if isinstance(value, list): # reverse时会将参数转化为特定str
# 将["book1"+"book2"]转换为"book1+book2"
book_url = "+".join(value)
return book_url
else:
raise RuntimeError("反转URL的参数必须为list")
register_converter(BookType, "book_type") #注册
# urls.py
urlpattern = [
path('article/<book_type:book_name>/', v.book_list, name="book_page")
]
# views.py
from django.urls import reverse
def book_list(request, book_name):
target_url = reverse("book_page", kwargs={"book_name": book_name})
# kwargs的book_name此时要求的是list类型,而book_name就是to_python中转换而来的list
return HttpResponse("book_name is: {0} ,target_url is: {1}".format(book_name, target_url))运行
- 运行