django视图之CBV

   今日概要:

   1、restful 规范(建议)

   2、django rest framework框架

 内容详细:

    0.FBV、CBV(要么写函数要么写类)

CBV,基于反射实现根据请求方式不同,执行不同的方法。:

内部原理怎么实现:所有python的框架django、.net、flask、只要支持CBV都可以通过反射来选择几种方法GET、POST等。

原理:

   url——>view方法——>调用dispatch方法(反射执行其他方法:GET/POST/DELETE/PUT)

注:http请求即method名字有哪些:

 整个流程如下图所示:

在view.py中进行

在一个路由系统里面,永远都是一个url对应一个函数.

在class  StudentsView(View)的副类里面:

 全部CBV流程代码如下:

# 继承django中继承view

class StudentsView(View):

    def dispatch(self, request, *args, **kwargs):
        # # return HttpResponse('dispatch')          #则GET、POST请求不管什么请求都返回‘dispatch’,因为dispatch执行完不往后走了,因为发送请求后执行View,View中调用dispatch
        # func = getattr(self, request.method.lower())  # 去对象里通过反射找到不同的方法
        # ret = func(request, *args, **kwargs)  # 把参数传递过去执行不同的方法
        # return ret  # 有一个返回值,让用户能看到.
        #if request.method=='GET':
        print('before')
        ret = super(StudentsView, self).dispatch( request, *args, **kwargs)   #执行视图函数
        print('after')
        return ret

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')  # 相当于if request.method == "GET":
        #     return render(request, 'login.html')

    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.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    # path('admin/', admin.site.urls),
      path (r'users/', views.users),
      path (r'students/', views.StudentsView.as_view()),
      path (r'teachers/', views.TeachersView.as_view()),
from django.views import View




class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        print('before')
        ret = super(MyBaseView, self).dispatch(request, *args, **kwargs)  #super不是简单的只找自己当前类的副类或者基类,而是去找对象的整个继承关系的下一个副类去找dispatch方法
        print('after')
        return ret


class StudentsView(MyBaseView, View):  #继承两个类,先继承左边的

    def get(self, request, *args, **kwargs):
        print('get方法')
        return HttpResponse('GET')  # 相当于if request.method == "GET":
        #   return render(request, 'login.html')

    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')




class TeachersView(MyBaseView, View):

    def get(self, request, *args, **kwargs):
        print('get方法2')
        return HttpResponse('GET2')  # 相当于if request.method == "GET":
        #  return render(request, 'login.html')

    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')

代码的一些解释:

 

 输出结果如下:

 补充小知识点:

面试题:1、csrf_token是基于django的中间件实现的,django的中间件里最多可以写几个方法?

答:process_request、process_view、process_response、process_exception(异常状况执行)、process_render_template(视图函数返回对象有render方法时执行)

中间件的执行流程:process_request——>process_view——>process_response.

 

 

 2、使用中间件做过什么?

——权限

——用户登录验证

——django的csrf_token是如何实现?答:是基于process_view这个中间件实现的——检查视图是否被装饰器:

@csrf_exempt 

 

装饰,作用是免除csrf认证。其内部的原理就是去请求体或cookie中获取token,根据token作校验。

csrf_token认证时,

第一:先判断函数是否加装饰器;第二:再做获取用户提交的token,检验是否遵循csrf_token规则。

3、csrf_token的两种设置方式:一种是中间件,一种是装饰器

情况一:

 

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',  # 全局全网站只要发指定请求都要遵循csrf_token要求.即安全验证.
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

 

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt  #代表这个函数免除csrf_token认证的装饰器
def users(request):
    user_list = ['alex', 'oldboy']
    return HttpResponse(json.dumps((user_list)))  # 将字典转换为字符串,将一个Python数据类型转换为json数据类型

以上截图表示全局或者全网站只要发指定请求都要遵循csrf_token要求。

情况二:

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_protect

@csrf_protect  #代表这个函数需csef认证
def users(request):
    user_list = ['alex', 'oldboy']
    return HttpResponse(json.dumps((user_list)))  # 将字典转换为字符串,将一个Python数据类型转换为json数据类型

 以上是FBV的认证,接下来为CBV的小知识:

 csrf是需要使用@method_decorator(csrf_exempt) 需要在dispatch方法中(单独方法无效)

方式一:

 

from django.views.decorators.csrf import csrf_exempt
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)   #装饰器得加在dispatch里面

    def get(self, request, *args, **kwargs):
        print('get方法')
        return HttpResponse('GET')  # 相当于if request.method == "GET":
        #   return render(request, 'login.html')

    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
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt,name
='dispatch') #name表示方法名。 class StudentsView(View): def get(self, request, *args, **kwargs): print('get方法') return HttpResponse('GET') # 相当于if request.method == "GET": # return render(request, 'login.html') 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装饰方法。 

 总结:

CBV部分:

       知识点一:本质:基于用户请求的方式和反射来实现

                         流程:路由——>View——>dispatch(反射)

                          取消csrf认证(装饰器要加到dispatch方法上且method_decorator装饰)  

                         扩展:

                             --csrf

                                       ——基于中间件的 process_view方法,在中间件全站使用

                                        ——装饰器给单独函数进行设置(认证或无需认证) 即以上的两种方式。

               

 

 

  

 

posted @ 2022-05-18 18:26  费皿啊  阅读(475)  评论(0)    收藏  举报