diango中的MTV——FBV/CBV以及装饰器的复用问题解决

MVC

M: model 模型 与数据库交互

V: view 视图 HTML

C:controller 控制器 流程 和 业务逻辑

MTV

M:model ORM

T:template 模板 HTML

V:view 视图 业务逻辑

Django中的视图

FBV

def add_publisher(request,*args,**kwargs):
	# 逻辑
	return  response

urls.py

  url(r'^add_publisher',add_publisher )

CBV

from django.views import View
class Addpublisher(View):
	def get(self,reuqest,*args,**kwargs)
        # 处理GET请求的逻辑
        self.request
        return  response
    
    def post(self,reuqest,*args,**kwargs)
        # 处理POST请求的逻辑
        return  response

urls.py

  url(r'^add_publisher',Addpublisher.as_view() )

CBV中不同的请求能找到相应函数执行的原因:
继承了View,程序加载的时候,执行View中的Addpublisher.as_view(),
Addpublisher.as_view()定义了一个view函数,返回view,通过反射获取请求方式对应的方法(get/post)。

as_view的流程:

1. 程序加载的时候,执行Addpublisher.as_view():

   定义了一个view函数,返回view

   url(r'^add_publisher',view )

2. 请求到来时,执行view函数:

   1. 实例化对象  ——》 self
   2. self.request = request
   3. 执行self.dispatch(request, *args, **kwargs)
      1. 判断请求方式是否被允许:
         1. 允许: 通过反射获取请求方式对应的方法(get/post)  ——》 handler
         2. 不允许:self.http_method_not_allowed  ——》 handler
      2. 执行handler,将它的结果返回

加装饰器

FBV

FBV 直接加

@login_required
def publisher(request):

CBV

解决装饰器加同时加在类和函数上时的参数导致的复用性问题:
不加method_decorator,加在类方法上,需要第一个参数需要是self,如果在login_required的inner括号里加上了self,函数便无法用这个装饰器了,所以装饰器加在类上时要借助method_decorator

from django.utils.decorators import method_decorator

登录验证的装饰器
def login_required(func):
    def inner(request, *args, **kwargs):
        # print(request.COOKIES)
        # is_login = request.COOKIES.get('is_login')
        # is_login = request.get_signed_cookie('is_login', salt='xxxx', default='')
        is_login = request.session.get('is_login')
        # print(request.path_info)
        # print(request.get_full_path())
        print(request.META.get('HTTP_ACCEPT'))

        print(is_login)
        if is_login != 1:
            # 没有登录 跳转到登录页面
            url = request.path_info
            return redirect('/login/?url={}'.format(url))
        ret = func(request, *args, **kwargs)

        return ret

        # if is_login == '1':
        #     # 登录
        #     ret = func(request, *args, **kwargs)
        #     return ret
        # else:
        #     url = request.path_info
        #     return redirect('/login/?url={}'.format(url))

    return inner



# 加在方法上
@method_decorator(login_required)
def get(self, request, *args, **kwargs):

# 重写dispatch方法,加在dispatch方法上
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
    ret = super().dispatch(request, *args, **kwargs)
    return ret

#直接找到父类的dispatch方法加上去 ——最简单!推荐!
@method_decorator(login_required,name='dispatch')
class Addpublisher(View)

# 加在类上
@method_decorator(login_required,name='post')
@method_decorator(login_required,name='get')
class Addpublisher(View)

posted @ 2019-12-19 21:30  谢国宏  阅读(343)  评论(0编辑  收藏  举报