Django之FBV / CBV和中间件

FBV / CBV 

FBV:function base view

 url(r'^index$',user)
路由
def users(request):
    return HttpResponse(‘OK’)
视图

CBV:class base view

url(r'^students/', views.StudentsView.as_view())
路由
from django.views import View

class StudentsView(View):

    def get(self,request,*args,**kwargs):
    return HttpResponse('GET')

    def post(self, request, *args, **kwargs):
    return HttpResponse('POST')

    def put(self, request, *args, **kwargs):
    return HttpResponse('PUT')

    def delete(self, request, *args, **kwargs):
    return HttpResponse('DELETE')
视图

CBV实现原理

  基于反射实现根据请求方式不同,执行不同的方法。具体实现流程:url中的as_view() —》 view方法 —》 dispatch方法(根据反射执行相应函数)

CBV中可以使用的方法:

 http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
from django.views import View
class RestApi(View):
    def dispatch(self,request,*args,**kwargs):
        func = getattr(self,request.method.lower())
        ret = func(request,*args,**kwargs)
        return ret

    def get(self,request,*args,**kwargs):
        return HttpResponse('get')

    def post(self,request,*args,**kwargs):
        return HttpResponse('post')

    def put(self,request,*args,**kwargs):
        return HttpResponse('put')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('delete')
手动实现dispatch方法
from django.views import View
class RestApi(View):
    def dispatch(self,request,*args,**kwargs):
        ret = super(RestApi, self).dispatch(request,*args,**kwargs)
        return ret

    def get(self,request,*args,**kwargs):
        return HttpResponse('get')

    def post(self,request,*args,**kwargs):
        return HttpResponse('post')

    def put(self,request,*args,**kwargs):
        return HttpResponse('put')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('delete')
手动继承dispatch方法

Django中间件

  django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下:

  每一个请求都是先通过中间件中的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止,返回到网页上。

中间件中可以定义4个方法,分别是:

  1. process_request(self,request) 发送请求
  2. process_view(self, request, callback, callback_args, callback_kwargs) 执行完 request 预处理函数并确定待执行的 view 之后,但在 view 函数实际执行之前。
  3. process_template_response(self,request,response)
  4. process_exception(self, request, exception) 收集错误信息
  5. process_response(self, request, response) 必须返回 HttpResponse 对象. 这个 response 对象可以是传入函数的那一个原始对象(通常已被修改),也可以是全新生成的。

执行顺序也是按照以上顺序执行的.

自定义中间件

from django.utils.deprecation import MiddlewareMixin

class test1(MiddlewareMixin):
    def process_request(self, request):
        print('wusir')

class test2(MiddlewareMixin):
    def process_request(self, request):
        print('jack')
View Code

注册中间件

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',
    'wusir.m1.test1',
    'wusir.m1.test2',
]
View Code

终端输出结果

wusir
jack
tom
[17/Dec/2018 17:08:04] "GET /app/aa HTTP/1.1" 200 2
View Code

PS:与mange.py在同一目录下的文件夹 wusir下的m1.py文件中的test1,test2类

中间件可以做什么

  •   权限
  •   用户登录验证
  •   Django的csrf的实现
情况一:
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', # 全站使用csrf认证
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt
@csrf_exempt # 该函数无需认证
def users(request):
    user_list = ['alex','oldboy']
    return HttpResponse(json.dumps((user_list)))

情况二:
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware', # 全站不使用csrf认证
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt
@csrf_protect # 该函数需认证
def users(request):
    user_list = ['alex','oldboy']
    return HttpResponse(json.dumps((user_list)))
为某个函数单独增加或取消CSRF认证

CSRF在CBV中的使用补充
  装饰器@csrf_exempt,@csrf_protect必须在dispatch方法中(单独方法无效)

方式一:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.utils.decorators import method_decorator
    class StudentsView(View):
        
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super(StudentsView,self).dispatch(request, *args, **kwargs)

        def get(self,request,*args,**kwargs):
            print('get方法')
            return HttpResponse('GET')

        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')

        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')

        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
方式二:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.utils.decorators import method_decorator

    @method_decorator(csrf_exempt,name='dispatch')
    class StudentsView(View):

        def get(self,request,*args,**kwargs):
            print('get方法')
            return HttpResponse('GET')

        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')

        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')

        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
View Code

 

posted @ 2018-12-17 17:18  WuSir_ZJ  阅读(233)  评论(0编辑  收藏  举报