urls参数转换器

  • 用于限制参数
  • from django.urls import converters查看converters
  • 默认的参数转换器

    1. DEFAULT_CONVERTERS = {
    2. 'int': IntConverter(),
    3. 'path': PathConverter(),
    4. 'slug': SlugConverter(),
    5. 'str': StringConverter(),
    6. 'uuid': UUIDConverter(),
    7. }
  • 各个值对应的类 ```python class IntConverter: regex = ‘[0-9]+’ #多个0-9

    def to_python(self, value):

    1. return int(value)

    def to_url(self, value):

    1. return str(value)

class StringConverter: regex = ‘[^/]+’ #除了/都可以

  1. def to_python(self, value):
  2. return value
  3. def to_url(self, value):
  4. 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}’

  1. #import uuid uuid.uuid4()这个函数返回的字符串类型
  2. def to_python(self, value):
  3. return uuid.UUID(value)
  4. def to_url(self, value):
  5. return str(value)

class SlugConverter(StringConverter): regex = ‘[-a-zA-Z0-9]+’ #返回-或者a到z或者A-Z或者0到0或

class PathConverter(StringConverter): regex = ‘.+’ #都可以

  1. - 用法
  2. ```python
  3. # urls.py
  4. # 参数转换器
  5. path('app/converter/<int:param>', v.url_converter)
  6. # path('app/converter/<str:param>', v.url_converter)
  7. # path('app/converter/<uuid:param>', v.url_converter)
  8. # path('app/converter/<path:param>', v.url_converter)
  9. # path('app/converter/<slug:param>', v.url_converter)
  10. # views.py
  11. def url_converter(request, param):
  12. 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参数转换器。
  • 步骤
    1. 定义一个类,直接继承自object
    2. 参考converters.py里类的结构。
      • 定义一个属性regex,这个属性是用来限制url转换器规则的正则表达式
      • 实现to_python(self,value),将URL参数的值转换,再传给视图函数
      • 实现to_url(self,value),在做URL反转的时候,将传进来的参数转换回原来的参数类型,然后拼接成一个正确的URL
    3. 将定义好的转换器,使用django.urls.converters.register_converter方法注册进Django中
  • 例子
    1. 需求:
      1. 实现一个获取文章列表的demo,用户可以根据 /articles/文章分类/的方式来获取文章。其中文字分类的格式是分类1+分类2+分类3的方式拼接。如果只有一个分类,无需+
      2. 文章分类参数传到视图函数之前要把这些分类分开存储到list中。比如参数是book1+book2,那么传到视图函数的时候就要编程['book1', 'book2']
      3. 在使用reverse反转的时候,限制传递文字分类的参数应该是一个列表,并且要将这个列表变成book1+book2类型
    2. 实现:
      1. 使用re_path(),用正则要判断URL的参数 ```python

        urls.py

        from django.contrib import admin from django.urls import path,re_path #导入re_path from book import views as v #导入视图函数

urlpatterns = [

  1. # ()表示一个整体
  2. # ?P<param_name>后面接对这个pram_name的格式描述
  3. # \w 表示0-9,a-z,A-Z,_
  4. # + 表示0个或多个
  5. # \+ 表示纯粹的+,就是+的转义
  6. re_path(r'article/(?P<book_name>\w+|(\w+\+\w+)+)/', v.book_list, name="book_page")

]

  1. ```python
  2. # views.py
  3. from django.shortcuts import render, HttpResponse
  4. from django.urls import reverse
  5. def book_list(request, book_name):
  6. target_url = reverse("book_page", kwargs={"book_name": "book1+book2"})
  7. # 默认参数传递是str
  8. return HttpResponse("book_name is: {0} ,target_url is: {1}".format(book_name, target_url))
  1. - 运行


参数转换器 - 图1

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


参数转换器 - 图2