Django(三)类视图

一、定义类视图

函数视图

# 函数视图
def register(request):
    if request.method == 'GET':
        # 处理GET请求,返回注册页面
        return HttpResponse('get 页面')
    # 处理POST请求,实现注册逻辑
    return HttpResponse('这里实现注册逻辑')

类视图

相比于flask中的视图,Django中除了可以使用函数视图外,还添加了类视图。使用类视图可以将视图对应的不同请求方式以类中的不同方法来区别定义。

from django.views.generic import View

class Register(View):

    def get(self, request):
        """处理GET请求"""
        print(request.method)
        return HttpResponse('get 页面')

    def post(self, request):
        """处理POST请求"""
        print(request.method)
        return HttpResponse('post 页面')

路由定义:

urlpatterns = [
    # 不同于函数路由,我们需要
    url(r'^demo',views.Register.as_view())
]

类视图优点:

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

二、类视图添加装饰

先定义一个装饰器,因为视图函数中都有一个request参数,所以我们直接第一个参数就是request

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

1、在URL配置中装饰

urlpatterns = [
    # 不同于函数路由,我们需要
    url(r'^demo',my_de(views.Register.as_view()))
]

from django.http import HttpResponse
from django.views.generic.base import View

class Register(View):
    def get(self, request):
        """处理GET请求,返回注册页面"""
        print(request.method)
        return HttpResponse('get 页面')
    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        print(request.method)
        return HttpResponse('post 页面')

此种方式最简单,但因装饰行为被放置到了url配置中,单看视图的时候无法知道此视图还被添加了装饰器,不利于代码的完整性,不建议使用

2、 在类视图中装饰

url(r'^demo',views.Register.as_view())

class Register(View):
    @my_de
    def get(self, request):
        """处理GET请求,返回注册页面"""
        print(request.method)
        return HttpResponse('get 页面')
    @my_de
    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        print(request.method)
        return HttpResponse('post 页面')

Django(三)类视图
说明:因为函数视图准备的装饰器,其被调用时,第一个参数用于接收request对象,而类视图中请求方法被调用时,传入的第一个参数不是request对象,而是self 视图对象本身,第二个位置参数才是request对象

在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器,method_decorator的作用是为函数视图装饰器补充第一个self参数,以适配类视图方法

-使用method_decorator

url(r'^demo',views.Register.as_view())

class Register(View):
    @method_decorator(my_de)
    def get(self, request):
        """处理GET请求,返回注册页面"""
        print(request.method)
        return HttpResponse('get 页面')
    @method_decorator(my_de)
    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        print(request.method)
        return HttpResponse('post 页面')

Django(三)类视图

-当然我们也可以将我们的装饰器进行修改,第一个参数是self,第二个参数是request对象就好了

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

路由

url(r'^demo',views.Register.as_view())

类视图

class Register(View):
    @my_de1
    def get(self, request):
        """处理GET请求,返回注册页面"""
        print(request.method)
        return HttpResponse('get 页面')
    @my_de1
    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        print(request.method)
        return HttpResponse('post 页面')

Django(三)类视图

3、构造Mixin扩展类

重写as_view() 方法,在as_view中进行装饰,让类装饰器继承我们的MIxin 扩展类。

class Mixi(object):
   @classmethod
   def as_view(cls,*args, **kwargs):
       view = super().as_view(*args,**kwargs)
       view = my_de(view)
       return view
       
class DemoView(Mixi,View):
   def get(self, request):
       print(request.method)
       return HttpResponse('ok')

   def post(self, request):
       print(request.method)
       return HttpResponse('ok')

三、中间件

中间件和flask中的请求钩子类似,在某个时机执行。

  • 定义中间件:

中间件工厂函数需要接收一个可以调用的get_response对象。

def simple_middleware(get_response):
    # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
	print('init')
    def middleware(request):
        # 此处编写的代码会在每个请求处理视图前被调用。
		print('请求之前')
        response = get_response(request)
        # 此处编写的代码会在每个请求处理视图之后被调用。
        print('请求之后')
        return response
    return middleware
  • 添加中间件到 setting.py 的 MIDDLEWARE 列表中
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middle_ware_demo.simple_middleware',
]

运行结果
Django(三)类视图