Django框架之視圖層與CBV與settings源碼解析

Django框架之視圖層與CBV與settings源碼解析

視圖函數必需要返回一個HttpResponse對象html

返回的 render 和 redirect 本質上也是HttpResponse對象,因此視圖函數必需要返回一個HttpResponse對象是正確的django

一、JsonResponse

一、序列化字典對象,對象中要是有非ASCII碼的字符須要將JSONResponse對象中的json_dumps_params = {'ensure_ascii': False} 默認爲True變爲Falsejson

from django.http import JsonResponse
user_dic = {'username':"Mr沈", 'password':'123'}
return JsonResponse(user_dic, json_dumps_params={'ensure_ascii': False})

二、序列化非字典格式數據,須要將safe改成False後端

from django.http import JsonResponse
l1 = [1,2,3,4,5]
return JsonResponse(l1, safe=False)

二、form表單上傳文件數據

HTML文件中經過method='post' 和 enctype="multipart/form-data"讓用戶提交數據框架

<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile">
    <input type="submit">
</form>

後端視圖層能夠經過request.FILES獲取文件數據函數

def home(request):
    if request.method == 'POST':
        # 獲取用戶上傳的文件數據
        print(request.FILES)
        file_obj = request.FILES.get('myfile')  # 文件句柄
        print(file_obj.name)  # 獲取文件名
        with open(file_obj.name,'wb') as f:
                for line in file_obj:
                    f.write(line)
​
    return render(request,'home.html')

三、render原理

from django.template import Template, Context
def re_render(request):
    tem = Template('<h1>{{ user_dic }}{{ user_dic.username }}</h1>')
    user_dic = Context({'user_dic': {'username': 'vicky', 'password': 123}})
    res = tem.render(user_dic)
    return HttpResponse(res)

四、FBV和CBV

視圖函數不必定就是一個函數,也能夠是一個類post

FBV:基於函數的視圖,直接在視圖層寫的函數url

CBV:基於類的視圖,在視圖層寫類spa

一、CBV基本寫法

一、首先在路由層中與視圖函數對應關係應該調用類方法as_view()code

url(r'^login/', views.MyLogin.as_view())

二、在視圖層中,調用View模塊,使定義的類繼承該模塊,在該類下寫全部的請求方式方法

from django.views import View
class MyLogin(View):
    def get(self, request):
        return render(request, 'login.html')
    def post(self, request):
        return HttpResponse('收到post請求')

類中的方法as_view()可以自動識別提交的是什麼請求執行MyLogin中的get或post方法

二、CBV源碼

爲何調用as_view方法就能自動執行對應的方法呢?咱們講究須要看CBV源碼了

一、首先as_view是由類來調用的,咱們猜測是普通的函數靜態方法 @staticmethod 或者是類的綁定方法 @classmethod 看源碼發現是類的綁定方法

二、因此執行url就至關於執行view函數,接下來咱們來看view函數幹了什麼

三、咱們要肯定self是咱們本身寫的類產生的對象,cls就是咱們本身寫的類,所以最後返回的self.dispatch會先從咱們本身寫的類的對象中查找,再從咱們本身寫的類中查找,若是沒有再從繼承的父類View中查找dispatch

四、最後咱們得出dispatch就是分發不一樣的請求方式到咱們本身寫的類的對應的方法,從而執行對應的方法

總結:as_view()返回的結果是 ---> view,view()函數返回的結果是 ---> dispatch(),在dispatch中進行獲取反射獲取請求方式,從而調用咱們自定義的類中的對應的方法,因此能夠自動識別提交的是什麼請求執行MyLogin中的對應的方法

五、settings配置源碼解析

Django有暴露給用戶的settings配置文件和內部本身默認的配置,咱們須要看內部默認的配置時,首先在settings文件中導入global_settings和settings查看內部默認的配置

from django.conf import global_settings, settings

點擊settings進入源碼進入此頁面可獲得

importlib模塊

能夠經過字符串路徑來獲取路徑中的屬性和方法

import importlib
res = 'conf.b'
md = importlib.import_module(res)  # 此方法獲取到對象
# 該方法最小單位是模塊 不能是模塊裏面的單個名字
print(md.name)

總結:用戶配置了就用用戶的,用戶沒有配置就用默認的配置

手動模擬Django配置文件所作的事

import importlib
import os
from lib.conf import global_settings

class Settings(object):
    def __init__(self):
        # 先循環遍歷項目默認的全局配置文件
        for name in dir(global_settings):
            # 判斷變量名是不是大寫
            if name.isupper():
                # 鍵值對設置給對象
                k = name  # NAME
                v = getattr(global_settings,name)  # jason
                setattr(self,k,v)

        # 先獲取暴露給用戶的配置文件的字符串路徑
        module_path = os.environ.get('xxx')  # conf.settings
        # 裏面importlib模塊 導入settings文件
        md = importlib.import_module(module_path)  # md = settings

        # 同上操做
        for name in dir(md):
            # 判斷變量名是不是大寫
            if name.isupper():
                # 鍵值對設置給對象
                k = name  # NAME
                v = getattr(md,name)  # jason
                setattr(self,k,v)

settings = Settings()
相關文章
相關標籤/搜索