1. 程式人生 > 其它 >11_04、Django請求生命週期流程圖

11_04、Django請求生命週期流程圖

一、Django請求生命週期流程圖

二、路由層

1、路由檔案

專案中url.py檔案中,新增路由設定

urlpatterns = [
    url(r'^test/', views.test),
]
r'^test/'  # 正則表示式,匹配以test開頭,以/結尾的字元,r是去掉轉義符,保證斜槓只是斜槓字元,而不會發生轉義
views.test # view.py檔案中的test函式記憶體地址

注意:settings.py檔案中的APPEND_SLASH控制斜槓自動匹配

APPEND_SLASH = True  # 控制斜槓自動匹配(預設)
APPEND_SLASH = False  #
取消斜槓自動匹配

2、有名分組和無名分組

1.什麼是分組

有名分組和無名分組是正則分組的兩種形式。

分組是通過括號把正則表示式括起來,特徵是組內優先展示。

路由檔案中的r'^test/'是一個正則表示式,所以也可以通過有名分組和無名分組的方式書寫

2.為什麼要用到分組

url中的前半部分(r'^test/'),是使用者輸入的網址字尾。

是為了給後半部分(views.test)這個函式名的記憶體地址匹配。

通過正則分組可以作為位置實參給函式傳參

但是注意,有幾個分組(引數),函式內就必須有相應的位置形參用於接收。

3、例項演示

有名分組:

# url.py檔案
urlpatterns = [
    url(r
'^test/(\d+)/(\a+)', views.test), ]
# view.py檔案
def test(request, first, second):
    print(first)  # (\d+)匹配的內容
    print(second)  # (\a+)匹配的內容
    return render(request, 'test.html', locals())

無名分組:

# url.py檔案
urlpatterns = [
    url(r'^test/(?P<year>\d+)/(?P<month>\a+)', views.test),  #
有名分組,給正則名稱:year,month ]
# view.py檔案
def test(request, first, second):
    print(first)  # (\d+)匹配的內容是關鍵字year
    print(second)  # (\a+)匹配的內容匹配的內容是關鍵字month
    return render(request, 'test.html', locals())

注意:如果引數太多,可以用*args,**kwargs接收

# view.py檔案
def test(request, args, **kwargs):
    print(*args)  
    print(**kwargs) 
    return render(request, 'test.html', locals())

3、反向解析

1、起別名

針對過長匹配的url,我們可以用name給其重新命名

urlpatterns = [
    url(r'^test/test1/test2/test3/', views.test, name='test'),  # 給r'^test/test1/test2/test3/'重新命名為test
]

2、反向解析

反向解析就是通過name反向解析出原來的url

後端反向解析

# view.py檔案
from django.shortcuts import reverse


def test(request):
    print(reverse('test'))  # /test/test1/test2/test3/
    return render(request, 'test.html', locals())

前端反向解析

# test.html檔案

<body>
    <a href="{% url 'test' %}">前端反向解析</a>
</body>

無名分組前端反向解析

 

無名分組後端反向解析

 

 

有名分組前端反向解析

 

有名分組後端反向解析

 

 

4、路由分發

1、為什麼要路由分發

 隨著時間和使用者的增多,我們的Django專案也會越來越大,那麼毫無疑問我們的總路由檔案也會也來越大

 

 

 這會導致專案非常難以維護,為此我們會把總路由分開到不同的應用下面去,這是受Django框架支援的。

Django支援每個應用下面有自己的:

# 1、url.py檔案
# 2、static資料夾
# 3、templates資料夾

2、怎麼路由分發

第一步:

把總路由複製到各個應用中,並修改

# app02中的urls.py

from django.conf.urls import url
from django.contrib import admin
from app02 import views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),

]
# app02中的urls.py

from django.conf.urls import url
from django.contrib import admin
from app03 import views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),

]

第二步:總路由分發(include)

方式一:

"""
總路由檔案urls.py
匯入include
給分路由重新命名
"""

from django.conf.urls import url, include
from django.contrib import admin
from app01 import views
from app02 import urls as app02_url
from app03 import urls as app03_url

# url.py檔案
urlpatterns = [

    # 總路由分發
    url(r'^app02/', include(app02_url),),
    url(r'^app03/', include(app03_url),),

]

方式二:

"""
總路由檔案urls.py
無需匯入
"""
from django.conf.urls import url, include
from django.contrib import admin
from app01 import views

# url.py檔案  

urlpatterns = [
    url(r'^app02/', include('app02.urls')),
    url(r'^app03/', include('app03.urls')),

]

第三步:效果展示

檢視app02

 

 檢視app03

5、名稱空間

我們再給路由起別名的時候,如果兩個url命名為相同的名字

在根據別名反向解析的時候,預設解析的是最後一個

如果要精準解析,這裡就要用到名稱空間的知識了(namespace = '自定義名稱空間名字')

# 總路由檔案urls.py

urlpatterns = [

    url(r'^app02/', include('app02.urls', namespace='app02')),
    url(r'^app03/', include('app03.urls', namespace='app03')),

]

方向解析的時候

from django.shortcuts import render,HttpResponse,reverse

def index(request):
    print(reverse('app02:test'))
    return HttpResponse('app02:index')

三、虛擬環境

應用於多個多個專案,每個專案需要應用不同的模組、版本。

虛擬環境就是一個純淨版的python直譯器,我們可以在這個虛擬環境上安裝每個應用需要的外掛

我們可以同時擁有多個虛擬環境

 

 

四、JsonResponse(json序列化)

json格式的資料用於跨語言傳輸,

序列化就是通過json通過把各種格式的語言轉換成二進位制,

反序列化就是通過json把二進位制語言轉換成各種格式的語言

後端中的序列化和反序列化:

序列化:json.dumps

反序列化:json.loads

前端中的序列化和反序列化:

序列化:JSON.stringify()

反序列化:JSON.parse()

注意:

  前後端分離的專案,需要永達json格式的資料

  混合專案開發專案,用不到json格式的資料

 

django框架通過對json進一步封裝,方便了我們實現資料的序列和反序列化

from django.http import JsonResponse


def my_json(request):
    my_dict = {'username': '魯迅', 'gender': 'male'}  # 字典型別
    my_list = [1, 2, 3]  # 非字典型別

    # res = json.dumps(my_dict, ensure_ascii=False)  # json轉碼
    # return HttpResponse(res)  # json序列化

    # return JsonResponse(my_json, json_dumps_params={'ensure_ascii': False})  # 字典型別的序列化
    return JsonResponse(my_list, safe=False)  # 非字典型別的序列化

五、CBV的書寫

 CBV和FBV是一個概念的東西

FBV:function base views,顧名思義,基於檢視的函式(views.py中的函式)

CBV:class base views,同理,基於檢視的類(views.py中的類)

'''views.py檔案'''

# cbv必須繼承View類
from django.views import View


class IndexClass(View):
    # 注意類中的方法名必須指定為八種請求方式中的一種,不能隨意指定
    # 八種方式:get post push
    def get(self, request):
        return HttpResponse('get')

    def post(self,  request):
        return HttpResponse('post')
'''urls.py'''

urlpatterns = [
    url(r'^my_cbv/', views.IndexClass.as_view()),
]

六、CBV的原始碼分析

 

 

七、form表單上傳檔案

之前我們學過get請求和post請求可以通過request.get和request.post接收請求資料

檔案也有自己的接收方式:request.FILES

'''views.py檔案'''

def my_form(request):
    if request.method == 'POST':
        print(request.GET)  # get請求的物件request.GET,此處為<QueryDict: {}>
        print(request.POST)  # post請求的物件request.POST,此處為<QueryDict: {}>
        print(request.FILES)  # 檔案物件在request.FILES,<MultiValueDict: {'myfile': [<InMemoryUploadedFile: 測試圖片.png (image/png)>]}>
        # request.FILES只接收檔案資料,其他請求一概不接收

        # 字典取值
        file_obj = request.FILES.get('myfile')
        print(file_obj.name)  # 檔案的名稱:微信截圖_20220313203813.png

        # 上傳檔案
        with open(file_obj.name, 'wb') as f:
            # 上傳檔案的時候要一行一行讀取,防止記憶體溢位
            for line in file_obj:
                f.write(line)
        # 上傳的檔案存放在專案的根目錄
    return render(request, 'my_form.html')
    {# HTML檔案 #}

    {#注意:form表單上傳檔案的兩個必須條件method="post" enctype="multipart/form-data"#}
    <form action="" method="post" enctype="multipart/form-data">
        <p>
            上傳檔案:<input type="file" name="myfile">
        </p>
        <input type="submit" value="提交">
    </form>
'''urls.py檔案'''

urlpatterns = [
    url(r'^my_form/', views.my_form),  # 上傳圖片
]

注意:上傳的檔案存放在專案根目錄 ,但是再次上傳圖片檔案,會把原先上傳的覆蓋掉

我們可以通過匯入隨機數重新命名,解決這個問題

'''views.py檔案'''

def my_form(request):
    if request.method == 'POST':
        print(request.GET)  # get請求的物件request.GET,此處為<QueryDict: {}>
        print(request.POST)  # post請求的物件request.POST,此處為<QueryDict: {}>
        print(request.FILES)  # 檔案物件在request.FILES,<MultiValueDict: {'myfile': [<InMemoryUploadedFile: 測試圖片.png (image/png)>]}>
        # request.FILES只接收檔案資料,其他請求一概不接收

        # 字典取值
        file_obj = request.FILES.get('myfile')
        print(file_obj.name)  # 檔案的名稱:微信截圖_20220313203813.png

        import uuid
        rend_str = uuid.uuid4()
        file_path = str(rend_str) + '.png'

        # 上傳檔案
        with open(file_path, 'wb') as f:
            # 上傳檔案的時候要一行一行讀取,防止記憶體溢位
            for line in file_obj:
                f.write(line)
        # 上傳的檔案存放在專案的根目錄
    return render(request, 'my_form.html')