[Django框架之視圖層]


[Django框架之視圖層]

視圖層

Django視圖層, 視圖就是Django項目下的views.py文件,它的內部是一系列的函數或者是類,用來專門處理客戶端訪問請求后處理請求並且返回相應的數據,相當於一個中央情報處理系統

小白必會三板斧

  • HttpResponse

    • 返回字符串類型的數據
  • render

    • 返回html頁面,還可以使用模板語法
  • redirect

    • 重定向

三板斧本質

django視圖函數必須要返回一個HttpResponse對象? 正確!

django視圖函數必須有一個返回值,並且返回值的數據類型必須是HttpResponse對象

# 研究三者源碼可以得出結論
# HttpResponse
class HttpResponse(HttpResponseBase):
    """
    An HTTP response class with a string as content.
    # 以字符串作為內容的HTTP響應類
    This content that can be read, appended to or replaced.
    # 可以讀取、添加或替換的內容
    """
    streaming = False

    def __init__(self, content=b'', *args, **kwargs):
        super(HttpResponse, self).__init__(*args, **kwargs)
        # 內容是一個字節串。參見' content '屬性方法
        # Content is a bytestring. See the `content` property methods.
        self.content = content 
        
# render        
def render(request, template_name, context=None, content_type=None, status=None, using=None):
        """
        Returns a HttpResponse whose content is filled with the result of calling
        django.template.loader.render_to_string() with the passed arguments.
        # 返回一個HttpResponse,它的內容中填充了調用的結果
		# django.template.loader.render_to_string()和傳遞的參數
        """
        content = loader.render_to_string(template_name, context, request, using=using)
        return HttpResponse(content, content_type, status)
  
# redirect內部是繼承了HttpRespone類

JsonResponse

給前端返回json格式的字符串

方式1:自己序列化

import json
def func(request):
    d = {'user':'jason好帥','password':123}    
    res = json.dumps(d,ensure_ascii=False)
    return HttpResponse(res)

方式2: JsonResponse

from django.http import JsonResponse
def func(request):
    d = {'user':'jason好帥','password':123}
    return JsonResponse(d)
 #  return JsonResponse(d,json_dumps_params={'ensure_ascii':False} )
    
ps:額外參數補充
    json_dumps_params={'ensure_ascii':False}  # 看源碼
    safe=False  # 看報錯信息
 
# JsonResponse返回的也是HttpResponse對象

上傳文件

前端form表單上傳文件注意事項
      1.method必須是post
      2.enctype參數需要修改為multipart/form-data

后端暫時需要注意的是
      1.配置文件中注釋掉csrfmiddleware中間件
      2.通過request.FILES獲取用戶上傳的post文件數據       
def func3(request):
    if request.method == 'POST':
        print(request.POST)
        file_obj = request.FILES.get('myfile')
        print(file_obj.name)  # 獲取文件名稱
        with open(r'%s'%file_obj.name,'wb') as f:
            for chunks in file_obj.chunks():
                f.write(chunks)
    return render(request,'func3.html')

FBV與CBV

FBV		基於函數的視圖
	FBV使用頻率較低(基礎階段)
	
CBV		基於類的視圖
	CBV實際開發項目使用頻率較高(高級階段)
	
views.py視圖層
	視圖函數
    	不僅僅可以是函數也可以是類
        	1.面向過程式編程
            2.面向對象式編程

FBV基於函數的視圖(Function base view)我們前面寫的視圖函數都是FBV
CBV基於類的視圖(Class base view)

視圖文件中除了用一系列的函數來對應處理客戶端請求的數據邏輯外,還可以通過定義類來處理相應的邏輯

CBV基本使用

# views.py
from django.shortcuts import render,HttpResponse,redirect
from django.views import View
class MyView(View):
    def get(self,request):
        return HttpResponse("get方法")
    def post(self,request):
        return HttpResponse("post方法")
    
# urls.py    
url(r'^func4',views.MyView.as_view())
"""為什么能夠自動根據請求方法的不同執行不同的方法"""

1. CBV與FBV路由匹配本質

# urls.py  
urlpatterns = [
    url(r'^func4',views.MyView.as_view()) # CBV寫法
    # 等價  CBV路由配置本質跟FBV一樣
    url(r'^func4',views.view) # FBV寫法
] 

2. CBV與FBV區別之突破口

知識點:函數名/方法名:加括號執行優先級最高

CBV寫的是 as_view() 加括號意味着在項目啟動就會執行
那么我們大膽猜測:
	 要么是被@staicmethod修飾的靜態方法,就是個普通函數沒有形參
 	 要么是被@classmethod修飾的類方法,類來調自動將類當做第一個參數傳入

3. 研究一下源碼

@classonlymethod  # 類方法,就把它看成@classmethod
def as_view(cls, **initkwargs):
    def view(request, *args, **kwargs): # view是as_view的閉包
        self = cls(**initkwargs)  # self = MyView()生成一個我們自己寫的類的對象
        """
        實例化出一個View類的對象,返回一個dispatch()函數,看着跟我們之前寫的
        視圖函數幾乎一毛一樣,那么我們找一下函數的上級函數沒有這個方法,最后在類
        里發現了這個dispatch()函數
        """
        return self.dispatch(request, *args, **kwargs)
    return view # 返回一個函數的內存地址

def dispatch(self, request, *args, **kwargs):
        # 獲取當前請求並判斷是否屬於正常的請求(8個)
        if request.method.lower() in self.http_method_names:
            # get請求  getattr(對象,'get')   handler = 我們自己寫的get方法
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)  # 執行我們寫的get方法並返回該方法的返回值
# 結論:as_view()最終干的事情就是根據request請求方式來執行視圖類的不同請求方法

總結:以后會經常需要看源碼,但是在看Python源碼的時候,一定要時刻提醒自己面向對象屬性方法查找順序,先從對象自己找,再去產生對象的類里面去找,之后再去父類找,看源碼只要看到了self點一個東西,一定要問自己當前這個self到底是誰。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM