• Django-路由层URLconf


    URL配置(URLconf)  本质是URL与要为该URL调用的视图函数之间的映射表

    简单的路由配置

    from django.urls import path,re_path 
    
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/',views.timer),
    
    
        
        # 导入re_path;^以什么开头,$是控制尾意思是不再加什么东西
        re_path(r'^articles/2003/$',views.special_case_2003),
        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),
      ([0-9]{4})分组(任意四个数字的组合,都可以运行),会以位置参数传给后面的函数,    
    ]

    注意:

    • 若要从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):  # 参数名需正确,顺序怎样都不影响
        return HttpResponse('year:%s,month:%s' % (year,month))

    路由分发

    URL为更好解耦,应用创建一个新的urls.py文件,存放与自己相关的urls;然后再在公共项目的urls里导入应用的urls

    导入include分发函数

    #demo urls.py
    from
    django.contrib import admin from django.urls import path,re_path,include from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('timer/', views.timer), # 路由分发 re_path(r"app01/",include("app01.urls")), # 第一种形式:是加着app01应用 re_path(r"^",include("app01.urls")), # 第二种形式,不用加app01应用即可执行 ]
    #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.year_archive), #([0-9]{4})分组(任意四个数字的组合,都可以运行),会以位置参数传给后面的函数 re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), # re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), re_path(r'^articles/(?P<y>[0-9]{4})/(?P<m>[0-9]{2})/(?P<d>[0-9]+)/$', views.article_detail), ]

    反向解析

    方法一:给url起一个别名,后嵌入到html中;每次改变URL名字,嵌入到html中的别名均不需改

    #urls
    from django.contrib import admin
    from django.urls import path
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
        path('login/',views.login,name='LOG') #给这个URL起的别名 name='LOG'
    ]
    
    
    # view
    def login(request):
            if request.method == 'GET':
                return render(request,"login.html")
            else:
                print(request.GET)
                print(request.POST)
                user=request.POST.get("user")
                pwd=request.POST.get("pwd")
    
                if user=='yuan' and pwd=='123':
                    return HttpResponse("OK")
                else:
                    return HttpResponse('登录失败')
    
    #html
    <form action="{% url 'LOG' %}" method="post">     # 格式 action="{% url 'LOG'%}",到 urls中找一个别名为 LOG的url
        用户名<input type="text" name="user">
        密码<input type="password" name="pwd">
        <input type="submit">
    </form>

    方法二:利用reverse反向解析函数,通过别名,解析出URL

    #app01/urls.py

    from django.contrib import admin from django.urls import path,re_path,include from app01 import views urlpatterns = [ #分发的url,在反向解析的时候 会加上app01 re_path(r'^articles/2003/$', views.special_case_2003,name='s_c_2003'), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive,name='y_a'), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[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), ]
    #view

    def
    special_case_2003(request): url=reverse("s_c_2003") #利用reverse反向解析函数,通过别名,解析出URL(在哪个函数中都无所谓);此URL不含正则,固不需参数 url=reverse('y_a',args=(1003,)) # articles/(?P<year>[0-9]{4}) 有正则表达式,需用一个参数,用一个4位数代替 print(url) # 获取的URL /app01/articles/1003/ return HttpResponse("special_case_2003") # HttpResponse里面写的是响应体的内容

    名称空间

    在项目中可能会在不同应用遇见相同的url别名,会反解错误;为避免反解错误,可以给应用添加不同的名称空间

    first_pro/urls.py

    from django.contrib import admin
    from django.urls import path,re_path,include
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
        path('login/',views.login,name='LOG'),
        #分发
        re_path(r"^app01/",include(("app01.urls","app01"))),#这条分发放置在app01这个名称空间里
        re_path(r"^app02/",include(("app02.urls",'app02'))),#名称空间不能重名
    ]

    app01/url.py

    from django.urls import path,re_path,include
    from app01 import views
    
    urlpatterns = [
    
        #分发的url,在反向解析的时候 会加上app01
        re_path(r'^articles/2003/$', views.special_case_2003,name='s_c_2003'),
        re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive,name='y_a'),
        re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[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),
        re_path('index/',views.index,name='index')
    ]

    app01/views

    def index(request):
        return HttpResponse(reverse("app01:index")) #加上名称空间app01

    ---------------app02同样操作---------------

    #app02/urls
    
    from django.urls import path,re_path,include
    from app02 import views
    
    urlpatterns = [
    
        re_path("index/",views.index,name='index')
    ]
    
    
    
    #app02/views.py
    
    from django.urls import reverse
    def index(request):
    
        return HttpResponse(reverse("app02:index")) #加上名称空间app02

    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. regex 类属性,字符串类型
    2. to_python(self, value) 方法,value是由类属性 regex 所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
    3. to_url(self, value) 方法,和 to_python 相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。

    操作步骤:

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

    url_convert.py

    class MonConvert:
        regex="[0-9]{2}"  # regex
    
        def to_python(self,value):
            return str(value)
    
        def to_url(self,value): # 用于反向解析
            return '%04d' % value

    first_pro/urls  注册自定义URL转换器

    from django.contrib import admin
    from django.urls import path,re_path,include,register_converter  #register_converter帮你把写好的转换器注册进去
    from app01.urlconvert import MonConvert #导入MonConvert;
    
    #注册自定义URL转换器,mm是自定义转化器的名字
    register_converter(MonConvert,'mm')
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('timer/', views.timer),
        path('login/',views.login,name='LOG'),
        path("articles/<mm:month>",views.path_month), # 注意是<mm:month>,路由分发,执行视图函数
    ]

    app01/view.py

    def path_month(request,month):
        print(month)
        print(type(month))
        return HttpResponse('path month')



  • 相关阅读:
    .Matrix-Alpha总结展望
    .Matrix测试随笔
    Beta冲刺--第三次冲刺随笔
    Beta冲刺--第二天随笔
    Beta冲刺--第一天随笔
    专业团队——Beta冲刺凡事预则立
    专业团队Alpha总结展望——前事不忘后事之师
    专业团队——(Alpha冲刺)测试随笔
    专业团队——Alpha冲刺汇总
    总结随笔
  • 原文地址:https://www.cnblogs.com/hexiaorui123/p/10498825.html
Copyright © 2020-2023  润新知