Django 框架2:urls.py路由設置

路由系統是把接收到的請求,根據網址進行匹配,指定處理請求的函數或類。


路由系統分類:

    網站框架路由系統一般分爲兩類,FBV,CBV,Django兩者都支持,但有的框架只支持一種。

    FBV(Function Base View ): 函數基於視圖,在views.py中,使用函數處理請求。

    CBV(Class Base View):類基於視圖,在views.py中,使用處理請求。



URLS.PY文件路由配置

    兩個功能,一個是直接轉到函數,一個是轉到下級urls.py路由

urlpatterns=[
    path(r'blog/', blog.views.index),
    path(r'bbs/', bbs.views.index)
]

    1、路由規則模塊匹配函數url,path,re_path:    

        Django 1.XX使用url函數,可以使用正則,可以使用固定字符串

        Django 2.XX以後使用path和re_path,

from django.conf.urls import url        # django 1.XX使用 url

from django.conf.urls import url, re_path        # django 2.XX 使用 url和re_path

from django.urls import path, re_path        # django 2.1X 以後集成,使用 path和re_path

        url:url()函數傳遞了四個參數,兩個必需:regex和view,以及兩個可選:kwargs,和name。也就是正則表達式和視圖是兩個必填參數。

                1.xx版本--完成正則和固定匹配

                2.xx版本--保留


        path:完成指定字符串或格式的匹配,函數 path() 具有四個參數,兩個必須參數:route 和 view,兩個可選參數:kwargs 和 name。即路由和視圖是必填參數

                2.1x以後版本-- 完成固定匹配

                

        re_path:正則匹配,path完成不了的匹配

                2.xx版本--原生位置django.conf.urls

                             --後集成位置django.urls


    2、path函數:

        格式:path(匹配規則, views視圖函數或類方法, **kwargs, name)

                  匹配規則:不支持正則,但自身提供了五種匹配模式

                        int 匹配0和正整數,如 1230
                        str 匹配任何非空字符串但不包括/,
                        slug 匹配字母、數字以及橫槓、下劃線組成的字符串。

                        uuid 匹配一個uuid對象,如 075194d3-6885-417e-a8a8-6c931e272f00。(該對象必須包括破折號—,所有字母必須小寫)
                        path 匹配所有的字符串 包括/(意思就是path前邊和後邊的所有)    

                        

                  views視圖或類方法:app的views.py的方法,或類方法

                  kwargs:向views傳遞的參數

                  name:後端反向解析,前端根據 name值找到解析路由


    3、path--匹配規則:

          一般分爲三種情況,嚴格匹配,帶參匹配,固定格式參數匹配

from django.urls import path, re_path
import index.views
import pathtest.views

urlpatterns = [
    path(r'pathtest/', pathtest.views.index),
    # r'pathtest/'嚴格匹配,前端使用pathtest/ 1 2 3傳參是會報錯。
    # The current path, pathtest/ 1 2 3, didn't match any of these.

    path(r'pathtest <id_1> <id_2>', pathtest.views.index),
    # 使用<>從url中捕獲值,pathtest/ 1,pathtest.views.index函數必須接收參數,否則報錯,可以是實參,也可以是kwargs
    # index() got an unexpected keyword argument 'id_1'

    path(r'pathtest <str:book_id>', pathtest.views.index),
    # 匹配str型的參數,並命名爲book_id,傳給views.index函數
    # str,int, slug, uuid, path,五種默認的匹配模式

]

    4、path--views視圖或類方法

        指定本條規則,處理請求的views.py的函數(FBV)或類(CBV):

        FBV:urls.py處理請求後,把請求交給函數index,index處理後,返回pathtest.html頁面給客戶端。

            urls.py

from django.urls import path, re_path
import index.views
urlpatterns = [
    path(r'pathtest <str:book_id>', pathtest.views.index),
    # str,int, slug, uuid, path,五種默認的匹配模式
]

            views.py

from django.shortcuts import render

def index(request,*args,**kwargs):
    para = []
    if kwargs:
        for k,v in kwargs.items():
            print(k,':',v)
    if args:
        for i in args:
            print(i)
    return render(request, 'pathtest.html', {'para': para})

        CBV:

        1、Class需要繼承django.views.generic 的View類

        2、URLS.py路由轉發到 APP.views.類.as_view()

        3、as_view()是繼承View類,不需要自己重寫

        4、查看generic\base.py  的as_view方法,看到是通過hasattr進行判斷用戶請求方式

                通過dispach 執行相對應的請求方法函數

        5、可以通過向 http_method_names註冊 新的方法實現自定義

        實例:

        http://127.0.0.1:8000/pathtest1/   顯示CBV1

        http://127.0.0.1:8000/pathtest2/   顯示CBV2

        URL.py

from django.urls import path, re_path
import pathtest.views
urlpatterns = [
    path(r'pathtest1/', pathtest.views.CBV1.as_view()),
    path(r'pathtest2/', pathtest.views.CBV2.as_view())
]

    APP:pathtest        Views.py

from django.view.generic import
class CBV1(View):
    def get(self,request,*args,**kwargs):
        return HttpResponse('<h1>CBV1</h1>')

class CBV2(View):
    def get(self,request,*args,**kwargs):
        return HttpResponse('<h1>CBV2</h1>')


    5、kwargs:向views傳遞的參數

            可以向views傳遞字典型參數,views函數可以使用實參或形參接收,使用形參接收時,通過path函數傳遞的參數始終在url網址傳遞的參數前。

        urls.py

urlpatterns = [path(r'pathtest1/<int:url_args>', pathtest.views.CBV1.as_view(),{'since':'O-K'})]
# 向views.py傳遞{'since':'O-K'}

        views.py

class CBV1(View):
    def get(self,request, *args, **kwargs):
    # 使用實參接收def get(self,request, since, *args, **kwargs):
        para = []
        if kwargs:
            for k,v in kwargs.items():
                print(k,':',v)
                para.append(v)
        return HttpResponse('<h1>CBV2{}</h1>'.format(para))
        
# 訪問:http://127.0.0.1:8000/pathtest1/0010 
# 網頁顯示:CBV2['O-K', 10]

        

      6、name: 定義後,使用{%url 'name值引用'%} ,url代指當前網址。

            views渲染HTML模板{%url 'name值' %}時,根據name值找到urls.py中對應的path路由,

              把path匹配規則字符串替換到 HTML模板的‘name值’

        urls.py

urlpatterns = [
path(r'pathtest1/', pathtest.views.CBV1.as_view()),                # 定義正向路由http://127.0.0.1:8000/pathtest1/訪問CBV1
path(r'pathtest2/<int:page_num>', pathtest.views.CBV2.as_view(), name='patht')        # 使用name定義反向
# path(r'lllllllllll/<int:page_num>', pathtest.views.CBV2.as_view(), name='patht')        # 使用name定義反向,匹配規則改變不影響name
]

        views.py

form django.shorsturc import HttpResponse, reverse
class CBV2(View):
    def get(self,request,page_num, *args, **kwargs):
        route_path=reverse('patht', args=(page_num,))
        # reverse,轉換成際的URL地址,patht是urls裏的name值,轉換成匹配值
        # args:地址裏的參數個數,幾個就寫幾個,比如四個(page_num1,page_num2,page_num3,page_num4)
        print(route_path)                # 打印出來
        return HttpResponse('<h1>CBV2:<br/>page_num:{}</h1>'.format(page_num))      #根據點擊的鏈接不同,獲取的返回值也不同

class CBV1(View):
    def get(self,request, *args,**kwargs):
        return render(request, 'pathtest.html')

        html:

<body>
\\使用patht的name名來定義網址路由,後面的123是獲取值,所以,三個鏈接都會執行views的CBV2
<a href="{% url 'patht' 100 %}">num</a>
<a href="{% url 'patht' 200 %}">numb/a>
<a href="{% url 'patht' 300 %}">numbe</a>
</body>

        結果:

            訪問:http://127.0.0.1:8000/pathtest1/,點擊html裏的任何鏈接都會執行CBV2,因爲定義了name值。

            點擊任意一個鏈接,views的route_path:/pathtest2/100


      7、自定義path匹配規則。    

            path裏默認有四個匹配規則,int,str,slug,uuid,path,

            也可以自定義匹配規則,步驟:定義類;使用register_converter 註冊;使用。

        urls.py

from django.urls import path, register_reverter
import pathtest.views

class NumLine:
# 第一步,定義類
    regex='[-0-9]+'
    def to_python(self, value):
        return str(value)                //可以進行類型的轉換和處理,再返回
    def to_url(self, value):
        return str(value)                //可以進行類型的轉換和處理,再返回

# 第二步,向轉換器裏註冊自定義類,並起個名numline
register_reverter(NumLine,'numline')
       
urlpatterns=[
path(r'pathtest1/', pathtest.views.CBV1.as_view()),
path(r'ppppppppp/ <numline:data1> <numline:data2>',pathtest.views.CVB2.as_view(),name='patht')
# 使用自義定的numline,匹配參數
]

    APP:pathtest  views.py

from django.shortcuts import HttpResponse, render, reverse
from django.views.generic import View

class CBV1(View):
    def get(self,request):
        return render(request,'pathtest.html')

class CBV2(View):
    def get(self,request,data1, data2):
        full_path = reverse('patht',args=(data1,data2))
        return HttpResponse('<h1>Full path:{}<br />CBV2:<br/>page_num:{},{}</h1>'.format(full_path, data1, data2))

        pathtest.html

<a href="{% url 'patht' '-0--' 1111 %}">number</a>        //字符型參數傳入時,一定要加引號
<a href="{% url 'patht' -2344 2222 %}">number</a>         //這裏的-不報錯,因爲識別成了負數
<a href="{% url 'patht'  3323 3333 %}">number</a>

        結果:訪問時,只識別傳入的-和0-9,其它參數報錯。


      8、path路由分發到APP的urls.py(二級路由)。   

            使用include方法進行指定,include從django.urls導入

            格式:path(r'pathreg/',include('app.urls'))   ,include('APP名.APP路由文件')

            project:    urls.py

from django.urls import path, include

urlparrents=[
path(r'pathreg/',include('pathtest.urls')),
]

            app:         urls.py

from django.urls import path, include
from pathtest import views
urlparrents=[
path(r'',views.CBV1.as_view()),
path(r'index/',views.CBV2.as_view()),
]

            app:        views.py

from django.shortcuts import HttpResponse
from django.views.generic import View

class CBV2(View):
    def get(self,request):
        return HttpResponse('<h1>index page</h1>')

class CBV1(View):
    def get(self, request):
        return HttpResponse('<h1>default page<h1>')

結果:http://127.0.0.1:8000/pathreg/,經過project的urls路由文件匹配pathreg,分發到app的urls路由文件,調用CBV1顯示default  page

          http://127.0.0.1:8000/pathreg/index,經過project的urls路由文件匹配pathreg,分發到app的urls路由文件匹配index,調用CBV1顯示index  page


      9、re_path:支持正則匹配,其它參數與path一樣

            與Django1.xx版本的url功能一樣

path(r'', views.CBV1.as_view()),

re_path(r'index$', views.CBV2.as_view()),
# http://127.0.0.1:8000/pathtest/1111111111111index

re_path(r'^index', views.CBV2.as_view()),
# http://127.0.0.1:8000/pathtest/index1111111111111

re_path(r'index', views.CBV2.as_view()),
# 這纔是重點,只要包含連續的index,都會找到DBV2

re_path(r'^[a-zA-Z][_0-9a-zA-Z]{5,9}$', views.CBV2.as_view())
# 匹配以字母開頭,後面由數字或下劃線或字母組成的最短是6,最長是10個字符的路徑
# 注意:{5,9}匹配6,10個字符,因爲開頭那個不算在{5,9}選項裏
# http://127.0.0.1:8000/pathtest/i_d111ex11 匹配


    10、給CBV增加自定義提交方法:   

             找到 django.views.generic .View類,

                默認提供了http_method_names列表裏的方法,

                as_view函數進行了一些參數等判斷,

               最後返回了dispach方法, 

                dispach通過反射(getattr)執行相應的函數


            增加自定義提示方法:

            1)向http_method_names列表添加方法名,http_method_names.append('kill')

            2)在app.views.py裏定義kill函數


            通過重寫dispach方法,給所有方法增加因定操作

    def dispatch(self, request, *args, **kwargs):
        print('操作前的操作')
        obj = super(Cbv,self).dispatch(request, *args, **kwargs)
        print('操作後的操作代碼')
        return obj




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章