06.类视图

01.类视图

1.1 函数视图弊端

  • 以函数的方式定义的视图称为函数视图,函数视图便于理解。
  • 但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时
  • 便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳。
 def register(request):
    """处理注册"""

    # 获取请求方法,判断是GET/POST请求
    if request.method == 'GET':
        # 处理GET请求,返回注册页面
        return render(request, 'register.html')
    else:
        # 处理POST请求,实现注册逻辑
        return HttpResponse('这里实现注册逻辑')

1.2 类视图引入

  • 在Django中也可以使用类来定义一个视图,称为类视图。

  • 使用类视图可以将视图对应的不同请求方式以类中的不同方法来区别定义。

  • 类视图的好处

    • 1)代码可读性好
    • 2)类视图相对于函数视图有更高的复用性, 如果其他地方需要用到某个类视图的某个特定逻辑,直接继承该类视图即可
  • 类视图原理

    • 1)调用流程 as_view-->view-->dispatch
    • 2)getattr('对象','字符串')
from django.views import View

class RegisterView(View):
    """类视图:处理注册"""

    def get(self, request):
        """处理GET请求,返回注册页面"""
        return JsonResponse({"name":"zhangsan"})

    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        return JsonResponse({"name":"zhangsan"})

02.类视图添加装饰器

  • 1、 dispatch是父类中用来反射的函数,找对应的函数(比对应函数先执行)

  • 2、 比如你发送post请求就可以通过dispatch找到对应的post函数进行处理,get就会找到get函数处理

添加路由


from django.urls import path, re_path
from app01 import views

urlpatterns = [
    re_path('home/', views.Home.as_view()),
]

2.1 定义一个装饰器

def my_decorator(func):
    def wrapper(request, *args, **kwargs):
        print('自定义装饰器被调用了')
        print('请求路径%s' % request.path)
        return func(request, *args, **kwargs)
    return wrapper

2.2 为特定请求方法添加装饰器

  • 在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器

  • 需要使用method_decorator将其转换为适用于类视图方法的装饰器。

  • method_decorator装饰器使用name参数指明被装饰的方法

 
from django.shortcuts import HttpResponse
from django.views import View
from django.utils.decorators import method_decorator

# 为全部请求方法添加装饰器
@method_decorator(my_decorator, name='dispatch')
class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

# 只给get请求添加装饰器
@method_decorator(my_decorator, name='get')
class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

2.3 为特定请求方法添加装饰器

from django.shortcuts import HttpResponse
from django.views import View
from django.utils.decorators import method_decorator

# 为特定请求方法添加装饰器
class DemoView(View):

    @method_decorator(my_decorator)  # 为get方法添加了装饰器
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    @method_decorator(my_decorator)  # 为post方法添加了装饰器
    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

    def put(self, request):  # 没有为put方法添加装饰器
        print('put方法')
        return HttpResponse('ok')

03.类视图Mixin扩展类

  • 使用面向对象多继承的特性,可以通过定义父类(作为扩展类)

  • 在父类中定义想要向类视图补充的方法,类视图继承这些扩展父类,便可实现代码复用。

  • 定义的扩展父类名称通常以Mixin结尾。

class ListModelMixin(object):
    """
    list扩展类
    """
    def list(self, request, *args, **kwargs):
        ...

class CreateModelMixin(object):
    """
    create扩展类
    """
    def create(self, request, *args, **kwargs):
        ...

class BooksView(CreateModelMixin, ListModelMixin, View):
    """
    同时继承两个扩展类,复用list和create方法
    """
    def get(self, request):
        self.list(request)
        ...

    def post(self, request):
        self.create(request)
        ...