1. 程式人生 > 程式設計 >Django中的CBV

Django中的CBV

CBV模式的介面

CBV模式即為API式的寫法,一個資源類接受一系列的請求。本文討論的是View的直接子類中的概念和方法,Django REST framework中重寫和添加了大量的方法,可以直接繼承自XXXAPIView,不再本文的討論範圍。

  • 首先在試圖函式中建立View的子類
  • 在類中定義請求方式的類方法
  • 在urlpatterns中新增方式不同,需要加as_view()
    • 需要加(),呼叫這個方法
class HelloView(View):
	def get(self,request):
		return HttpResponse("GET view ok")
複製程式碼

View中的方法

  1. __init__
  2. as_view
  3. dispaych
  4. http_method_not_allowed
  5. options
  6. __allowed_methods
  7. http_method_name

呼叫順序為

as_view

  • as_view
  1. as_view傳入的引數不能和請求方法同名
	def get(self,request):
        return HttpResponse("GET %s" % self.msg)
複製程式碼
  1. as_view傳遞進來的引數必須是類中既有的屬性
  • 定義view函式
  1. 建立自己的物件
def as_view(resquest):
	def view(cls)
		self = cls(**initkwargs)
複製程式碼
  1. 記錄傳入的引數HelloView
  2. 只要支援get請求就支援head請求
  3. 在view函式中呼叫了dispatch

dispatch

  1. 根據請求方法名字小寫取既有請求方法列表中判定
def dispatch(self,request,*args,**kwargs):
	if request.method.lower() in self.http_method_names:
	handler = getattr(self,request.method.lower(),self.http_method_not_allowed)
	else:
        handler = self.http_method_not_allowed
    return
handler(request,**kwargs) 複製程式碼
  • 如果請求不存在直接返回http_method_not_allowed
  • 如果存在,會根據請求方法獲取對應的屬性
    • 屬性不存在也返回http_method_not_allowed
    • 屬性存在返回正常屬性
  • 呼叫屬性

http_method_not_allowed

  • 直接返回HttpResponse

_allowed_methods

  • 用列表迭代器,返回請求方法的名字
return [m.upper() for m in self.http_method_names if hasattr(self,m)]
複製程式碼

options

  • 是一個請求方法
  • 預設所有的CBV都支援options方法

類試圖CBV流程

as_view

通過內建方法dispatch來分發請求方法

重寫View父類,實現繼承自重寫類的類,可以支援請求方法

class HelloCustomView(object):
    @classmethod
    def as_view(cls):
        def view(request):
            self = cls()
            return self.dispatch(request)
        return view

    def dispatch(self,request):
        handler = getattr(self,None)
        if not handler:
            return HttpResponse("request method not allowed")
        return handler(request)

    def get(self,request):
        return HttpResponse("GET")

    def post(self,request):
        return HttpResponse("POST")

    def put(self,resquest):
        return HttpResponse("PUT")
複製程式碼

TemplateView

繼承關係如圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-gSkf4aVq-1573007279134)(github.com/belingud/im…)]

有三個父類

  • TemplateResponseMixin
  • ContextMixin
  • View
    • 用來分發請求的父類

TemplateResponseMixin

  • 屬性
    • template_name
    • template_engine
    • response_class
    • content_type
  • 方法
    • render_to_respose
      • 將傳入的上下文渲染形成響應
    • get_template_names
  • 作用
    • 用來渲染模板的多繼承類

ContextMixin

  • 屬性
  • 方法
    • get_context_data
  • 作用
    • 一個將傳入的鍵值對轉化為'view'鍵字典的預設多繼承父類

View

  • 屬性
    • http_method_names
  • 方法
    • as_view
      • view
    • dispatch
    • http_method_not_allowed
    • options
  • 作用
    • 用來分發請求

TemplateView實現的功能:

  1. 分發請求:dispatch方法
  2. 實現了get請求:在TemplateView類中的get方法
  3. 獲取上下文:ContextMixin多繼承父類
  4. 渲染成響應:TemplateResponseMixin中的render_to_respose方法

ListView

繼承關係如圖

[外鏈圖片轉存失敗,建議將圖片儲存下來直接上傳(img-BIF0IjzQ-1573007279135)(github.com/belingud/im…)]

ListView只是繼承父類,沒有在其中增改方法

有兩個父類

  • MultipleObjectTemplateResponseMixin
  • BaseListView

MultipleObjectTemplateResponseMixin的屬性和方法

屬性:

  1. template_name_suffix = '_list'

方法:

  1. def get_template_names(self):返回模板名字的列表

BaseListView的屬性和方法

無屬性

方法:

  • get():將傳入的上下文渲染成響應,預設支援get請求
return self.render_to_response(context)
複製程式碼

MultipleObjectTemplateResponseMixin

有一個父類

TemplateResponseMixin

也是View的父類,屬性和方法同上文的TemplateResponseMixin

BaseListView

有兩個父類

  1. MultipleObjectMixin

他有一個父類ContextMixin,父類的類方法 get_context_data 將傳入的鍵值對轉化為’view’鍵字典的預設多繼承父類

屬性:

  • allow_empty
  • context_object_name
  • model
  • ordering
    • 以某個欄位排序,可以制定多個
  • page_kwargs
  • paginate_by
  • paginate_class
  • paginate_orphans
  • queryset

傳入一個model或者query_set,返回modelname_list,否則預設為object_list

model = Book  # 或下面的query_set
queryset = Book.objects.all()
複製程式碼

方法:

  • get_queryset
  • get_ordering
  • paginate_queryset
  • get_paginate_by
  • get_paginator
  • get_paginate_orphans
    • 返回最後一個頁碼
  • get_allow_empty
  • get_context_object_name
  • get_context_data
    • 用來重寫
  1. View

即上文中的View

流程概覽

graph LR
  A[url] --> B[as_views]
  B[as_views]-->C[dis_patch]
  C[dis_patch]-->D[get]
  D[get]-->E[get_queryset]
  E[get_queryset]-->F[get_context_data]
  F[get_context_data]-->G[render_to_response]
複製程式碼
graph TD

A[get_queryset]-->B[queryset屬性和model屬性]

A[get_queryset]-->C[get_ordering]
A[get_queryset]-->D[get_allow_empty]

複製程式碼
graph TD
 A[get_context_data]-->B[get_paginate_by]
 A[get_context_data]-->C[get_context_object_name]
 A[get_context_data]-->D[向context中注入資料]

複製程式碼