Django2.0-urls(3)-参数转换器

urls参数转换器

  • 用于限制参数

  • from django.urls import converters查看converters

  • 默认的参数转换器

    DEFAULT_CONVERTERS = {
        'int': IntConverter(),
        'path': PathConverter(),
        'slug': SlugConverter(),
        'str': StringConverter(),
        'uuid': UUIDConverter(),
    }
    
  • 各个值对应的类

    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 = '.+' #都可以
    
    
  • 用法

    # 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开发的例子

  • 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的参数

        #urls.py
        from django.contrib import admin
        from django.urls import path,re_path #导入re_path
        from book import views as v #导入视图函数
        
        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")
        ]
        
        # 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))
        
        • 运行

          run1

      2. 更改

        # 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))运行
        
      • 运行

        run2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值