类视图

类视图

Django视图

    Django视图有两种:

  • 基于函数的视图(Function Base View)
  • 基于类的视图(Class Base View)

类视图

基本使用

   urls.py:

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.LoginView.as_view()),
]

views.py:

from django.shortcuts import render, HttpResponse
from django.views import View

# Create your views here.


class LoginView(View):

    def get(self, request):
        """GET请求"""
        return render(request, 'login.html')

    def post(self, request):
        """POST请求"""
        HttpResponse('OK')

@method_decorator

    在类视图中使用为函数准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器。

# 为全部类请求方法添加装饰器
@method_decorator(login_required, name='dispatch')
class Room_book_view(View):
    
    def get(self, request):
        pass

    def post(self, request):
        pass

# 为特定请求方法添加装饰器
@method_decorator(login_required, name='get')
class Room_book_view(View):

    def get(self, request):
        pass

    def post(self, request):
        pass

    如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(),可以直接在需要添加装饰器的方法上使用method_decorator。

class Room_book_view(View):
    @method_decorator(login_required)
    def get(self, request):
        pass

    def post(self, request):
        pass

CBV源码解析

1 views.LoginView.as_view()

    此为LoginView的as_view类方法,由于类LoginView中无此类方法,所以在父类View中查找,类View存在此方法,代码如下:

class View:
    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    @classonlymethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            return self.dispatch(request, *args, **kwargs)
        return view

    所以,执行view.LoginView.as_view(),返回值为view,也即:

    path('login/', views.LoginView.as_view())     ---------->     path('login/', view)

2 URL请求

    当浏览器向服务器发送http://127.0.0.1:8000/login/请求时,此时执行view函数,返回值为self.dispatch(request, *args, **kwargs),由于类LoginView中无dispatch方法,则在父类View中查找,类View中存在此方法,代码如下:

def dispatch(self, request, *args, **kwargs):
    if request.method.lower() in self.http_method_names:    #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed) 
    else: 
        handler = self.http_method_not_allowed 
    return handler(request, *args, **kwargs)

    由于此请求为GET请求,所以'get'在http_method_names中,handler = self.get,所以dispatch方法返回值为self.get(request, *args, **kwargs)。self指向类LoginView的实例。所以此GET请求最终执行的是LoginView中的get方法(方法名不可为其他)。

    同理,post/put/patch/delete/head/options/trace请求执行过程与GET请求一致。

posted @ 2019-03-04 21:25  Ethan_Y  阅读(158)  评论(0)    收藏  举报