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 valuedef 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.pydef 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.pyfrom django.shortcuts import render, HttpResponsefrom django.urls import reversedef book_list(request, book_name):target_url = reverse("book_page", kwargs={"book_name": "book1+book2"})# 默认参数传递是strreturn HttpResponse("book_name is: {0} ,target_url is: {1}".format(book_name, target_url))
- 运行

1. 更改
# app中的 converters.py(自己新建)# 然后在app中的 __init__.py中 from * inport convertersfrom django.urls import register_converterclass BookType(object):regex = "\w+|(\w+\+\w+)+" #对参数的判别def to_python(self, value): #path中使用的时候会将参数转化为list# 将"book1+book2"转换为["book1", "book2"]book_list = value.split("+")return book_listdef to_url(self, value):if isinstance(value, list): # reverse时会将参数转化为特定str# 将["book1"+"book2"]转换为"book1+book2"book_url = "+".join(value)return book_urlelse:raise RuntimeError("反转URL的参数必须为list")register_converter(BookType, "book_type") #注册
# urls.pyurlpattern = [path('article/<book_type:book_name>/', v.book_list, name="book_page")]
# views.pyfrom django.urls import reversedef book_list(request, book_name):target_url = reverse("book_page", kwargs={"book_name": book_name})# kwargs的book_name此时要求的是list类型,而book_name就是to_python中转换而来的listreturn HttpResponse("book_name is: {0} ,target_url is: {1}".format(book_name, target_url))运行
- 运行

