zoukankan      html  css  js  c++  java
  • django之路由分发

    路由分发决定哪一个路由由哪一个视图函数来处理。

    注意:django2.0里的re_path和django1.0里的url除了名字不一样,其他都一样。

    简单配置

    from django.urls import path,re_path
    
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/',views.timer),
    
    
        # 路由配置:  决定哪一个路由由哪一个视图函数来处理
        # repath和django1.0里的url用法一样
        # 不写^,articles前面可以写任何东西(edward/123/articles);同理,不写$,2003后面也可以写任何东西。
        re_path(r'^articles/2003/$',views.special_case_2003),
    
        # 正则匹配年份
        # 如果是2003,会匹配第一个
        # 如果去掉$就不走第三个了,因为匹配到年份那就不往后匹配了,而是直接执行arvhive_year了。
        re_path(r'^articles/([0-9]{4})/$',views.archive_year), # year_archive(request,1999)。django2.1.5不用传第二个参数了
    
        re_path(r'^articles/([0-9]{4})/([0-9]{2})/$',views.month_archive),
    
        # re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
    ]

    注意:

    • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。

    • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles

    • 每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

    有名分组

    # urls
        # 有名分组,?P<year>相当于是起了个名字,然后把名字当做参数传给视图函数,后面才是正则部分。
        re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive),
       '''
       month_archive(request,year=2009,momth=12)  
       这样在views视图,不管传入的参数的顺序是什么,year就是year,month就是month,但是名字必须是year和month
       '''
    
    #views
    def month_archive(request, month,year):  # 顺序颠倒也没有问题,不管顺序是什么都会正常显示year和month
        return HttpResponse('year:%s,month:%s' % (year,month))

    路由分发

    在app01下面重新创建一个urls的文件,把关于app01的url放到里面,然后再在公共项目的urls里导入app01的urls

    # app01 urls.py
    from django.urls import path, re_path
    
    from app01 import views
    
    urlpatterns = [。
        re_path(r'^articles/2003/$', views.special_case_2003),
        re_path(r'^articles/([0-9]{4})/$', views.archive_year),  # year_archive(request,1999)。
        re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    ]
    
    # demo urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
    
        # 分发:
        re_path(r'^app01', include('app01.urls')),   
        # re_path(r'^', include('app01.urls')   #  路径里面不用写app01了
    ]

    反向解析

     反向解析就是给url起一个别名,我们用别名去找这个url就行,这样不管url如何改变,我们都可以用别名找到它。

    1. 在模板中进行反向解析

    urls.py

    from django.urls import path, re_path, include
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
        path('login.html/',views.login,name='Log'),
    
        # 分发:
        re_path(r'^', include('app01.urls')),
    ]

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Login</title>
    </head>
    <body>
    
    <!-- 在render的时候,去urls里找一个name叫Log的url,这样action里永远都是最新的url -->
    <form action="{% url 'Log' %}" method="post">
        用户名 <input type="text" name="user">
        密码 <input type="password" name="pwd">
        <input type="submit">
    </form>
    
    </body>
    </html>

    2. 在视图函数里进行反向解析

    # app01 urls
    
    re_path(r'^articles/2003/$', views.special_case_2003,name ='s_c_2003'),
    re_path(r'^articles/([0-9]{4})/$', views.archive_year,name='y_a'),
    
    from django.urls import reverse
    def special_case_2003(request):
        url = reverse('s_c_2003')  #  不需要参数,因为不含正则是一个完整的url,找到后直接匹配
        url2 = reverse('y_a',args=(4009,))   #  ^articles/([0-9]{4})/ 需要给一个四位数字的参数,匹配正则,参数可以是任意四位数字,具体数字按需求写。
        print(url)  # /articles/2003/
        print(url2)  # /articles/4009/
        return HttpResponse("<h3>special_case_2003</h3>")  # HttpResponse里面写的是响应体的内容

    命名空间

    主项目 urls.py

    from django.urls import path, re_path, include
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
        path('login.html/', views.login, name='Log'),
    
        # 分发:
        # 命名空间不可以重名
        re_path(r'^app01', include(('app01.urls', 'app01'))),
        re_path(r'^app02', include(('app02.urls', 'app02'))),
    ]

    app01

     # urls
    re_path('index/',views.index,name='index')
    
    # views
    def index(request):
    
    
        # return HttpResponse(reverse('index'))  # 找到的也是app02的index,用名称空间解决这个问题。
    
        # 用命名空间解决
        return HttpResponse(reverse('app01:index')) # # 冒号之前是namespace,冒号之后是名字

    app02

    # urls
    re_path('index/',views.index,name='index')
    
    # views
    def index(request):
    
        # return HttpResponse(reverse('index'))  # 找到的app02的index,用命名空间解决名字冲突的问题
    
        return HttpResponse(reverse('app02:index'))

    path方法(django2.0)

    re_path有两个问题:

     

    1.不能进行字符转换。

    def month_archive(request, month, year):
        print(type(month))  # str
        print(type(year))  # str
        return HttpResponse('year:%s,month:%s' % (year, month))

    2.同样的正则表达式,需要写多遍,不易于维护。

    urlpatterns = [  
        re_path('articles/(?P<year>[0-9]{4})/', year_archive),  
        re_path('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),  
        re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),  
        re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),  
    ]

    而path可以解决这两个问题

    # urls
    from django.urls import path
    path('articles/<int:year>',views.path_year)
    
    #views
    def path_year(request,year):
        print(type(year))   # int
        return HttpResponse('path year')

    基本规则:

    • 使用尖括号(<>)从url中捕获值。

    • 捕获值中可以包含一个转化器类型(converter type),比如使用 <int:name> 捕获一个整数变量。若果没有转化器,将匹配任何字符串,当然也包括了 / 字符。

    • 无需添加前导斜杠。

    path转换器

    Django默认支持以下5个转化器:

    • str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式

    • int,匹配正整数,包含0。

    • slug,匹配字母、数字以及横杠、下划线组成的字符串。

    • uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

    • path,匹配任何非空字符串,包含了路径分隔符

    自定义path转换器

    在实际开发中,django自带的转换器是不能满足我们的需求的,这就需要自定义转换器了

    操作步骤:

    1.在app里创建一个类,写自定义转换的规则

    url_convert.py

    class MonConvert:
        regex = "[0-9]{2}"   # 只能叫regex
    
        def to_python(self, value):
            return int(value)  #  不转化就是字符串,可以根据需求做任何操作。
    
        def to_url(self, value):  # 用于反向解析
            return "%04d" % value

    2.在urls里注册自定义转换器

    from django.urls import path, re_path, include,register_converter
    from app01.url_convert import MonConvert
    
    # 注册自定义转换器
    register_converter(MonConvert,'mm')

    3.在路由分发里使用自定义转换器

    urlpatterns = [
        path('articles/<mm:month>',views.path_month),
    ]

    Registering custom path converters

    For more complex matching requirements, you can define your own path converters.

    A converter is a class that includes the following:

    • regex class attribute, as a string.
    • to_python(self, value) method, which handles converting the matched string into the type that should be passed to the view function. It should raise ValueError if it can’t convert the given value.
    • to_url(self, value) method, which handles converting the Python type into a string to be used in the URL.

  • 相关阅读:
    PDF文件中的Form保存问题
    Understanding IP Fragmentation
    tcp ip guide IPsec IKE
    Windows安全事件日志中的事件编号与描述
    Cisco PIX fix up and Juniper firewall FTP ALG
    很好的IPSec介绍,详细解释了IKE协商的2个阶段的作用
    virtualbox 下运行Ubuntu 8.10的分辨率和guest additions的问题。
    Fixing the ‘Do you want to display nonsecure items’ message
    windows xp 开始菜单里面所有项目右键不起作用。
    HP backup and recovery manager
  • 原文地址:https://www.cnblogs.com/lshedward/p/10351098.html
Copyright © 2011-2022 走看看