1. 程式人生 > 實用技巧 >Python學習第147天(Django之檢視層)

Python學習第147天(Django之檢視層)

views 檢視層

小白必會三板斧
1.HttpResponse
2.render
3.redirect
django檢視函式必須要返回一個HttpResponse物件

前後端分離

前端一個人幹(前端轉成自定義物件)
JSON.stringify() json.dumps()
JSON.parse() json.loads()
後端另一個幹(python後端用字典)
只要涉及到資料互動,一般情況下都是用的json格式
後端只負責產生介面,前端呼叫該介面能拿到一個大字典
後端只需要寫一個介面文件 裡面描述字典的詳細資訊以及引數的傳遞

JsonReponse

import json
from django.http import JsonResponse
def reg(request):
    data = {'name':'haha哈哈', 'age':24}
    # 字典要想在前端展示出來,需要先序列化成字串,才能基於網路二進位制傳輸
    res = json.dumps(data,ensure_ascii=False)  # 傳輸的漢字不轉碼
    return HttpResponse(res) # json方法
return JsonResponse(data,json_dumps_params={'ensure_ascii
':False}) # JsonResponse 方法 ​ lis = [1,2,3,4,5] print(request.path) print(request.get_full_path()) return JsonResponse(lis, safe=False) # 如果返回的不是字典 只需要修改safe引數為false即可

上傳檔案

form表單上傳檔案需要注意:

1.enctype需要由預設的urlencoded變成multipart/form-data
2.method需要由預設的get變成post
3.目前還需要考慮的是 提交post請求需要將配置檔案中的csrf中介軟體註釋
    
# 'django.middleware.csrf.CsrfViewMiddleware', 4.如果form表單上傳檔案,後端需要在request.FILES獲取檔案資料,而不再是POST裡面

def file(request):
    if request.method == 'POST':
        # 檔案不在post的字典中
        file_obj = request.FILES.get('myfile')
        print(file_obj)  # 檔案物件
        print(file_obj.name)  # 檔名
# 操作檔案 將檔案寫入後端
        with open(file_obj.name, 'wb') as f:
            for line in file_obj.chunks():  # file_obj 是一個可迭代物件
                f.write(line)
        return HttpResponse('收到')
​
    # 先將上傳檔案頁面發到前端
    return render(request,'file.html')

FBV與CBV

FBV(基於函式的檢視) 面向函數語言程式設計

CBV(基於類的檢視) 面向物件式程式設計

views.py 檔案中
from django.views import View
​
class MyLogin(View):
    def get(self,request):
        print("from MyLogin get方法")
        return render(request,'login.html')
    def post(self,request):
        return HttpResponse("from MyLogin post方法")
urls.py 檔案中
url(r'^login/',views.MyLogin.as_view())

問題:

基於CBV的檢視函式 get請求來就會走類裡面get方法,post請求來就會走類裡面post方法 為什麼??

研究方向:

1.從url入手
url(r'^login/',views.MyLogin.as_view())  #由於函式名加括號執行優先順序最高,所以這一句話一寫完會立刻執行as_view()方法
​
                        
@classonlymethod
def as_view(cls, **initkwargs):  # cls就是我們自己的寫的類 MyLogin
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)  # 例項化產生MyLogin的物件  self = MyLogin(**ininkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        # 上面的幾句話都僅僅是在給物件新增屬性
        return self.dispatch(request, *args, **kwargs)  # dispatch返回什麼 瀏覽器就會收到什麼
        # 物件在查詢屬性或者方法的時候 你一定要默唸 先從物件自己這裡找  然後從產生物件的類裡面找  最後類的父類依次往後
    return view
                        
通過原始碼發現url匹配關係可以變形成
url(r'^login/',views.view)  # FBV和CBV在路由匹配上是一致的 都是url後面跟函式的記憶體地址
2.當瀏覽器中輸入login 會立刻觸發view函式的執行
def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    # 我們先以GET為例
    if request.method.lower() in self.http_method_names:  
        # 判斷當前請求方法是否在預設的八個方法內
        # 反射獲取我們自己寫的類產生的物件的屬性或者方法
        # 以GET為例  handler = getattr(self,'get','取不到報錯的資訊')
        # handler = get(request)
        handler = getattr(self,request.method.lower(),self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)  # 直接呼叫我們自己的寫類裡面的get方法
# 原始碼中先通過判斷請求方式是否符合預設的八個請求方法 然後通過反射獲取到自定義類中的對應的方法執行