Loading

CBV与FBV

FBV

FBV(function base views)就是在 url 中一个路径对应一个函数

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index)
]

views.py

def index(request):
    return render(request, 'index.html')

CBV

CBV(class base views) 就是在视图里使用类处理请求,它是基于反射实现,根据请求的方式不同,去执行不同的方法

流程:路由 --- View函数 --- dispatch执行反射

urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^students/', views.StudentsView.as_view()),
]

views.py

from django.views import View

class StudentsView(View): 

    def dispatch(self, request, *args, **kwargs):
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

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

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

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

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

请求进来,先执行这个 dispatch() ,然后调用父类 Viewdispatch()

# View 的 dispatch()

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

第一个参数 selfStudentsView 的对象,然后执行 getattr,返回 handler(request, *args, **kwargs),相当于找到了 StudentsView 写的 get 方法,执行返回结果 HttpResponse('GET') ,将这个结果交给 ret , ret 再返回给用户,所以看到的就是 GET

补充

django中间件的几个方法

  • process_request
  • process_view
  • process_template_response
  • process_exception
  • process_response

django的csrf_token是如何实现的

  • process_view方法实现,检查视图函数是否被 @csrf_exempt,用来免除 csrf 认证
  • 去请求体或 cookie 中获取 token

FBV知识点:给视图函数添加装饰器

情况一

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_protect

@csrf_protect	# 该函数需要认证
def users(request):
    user_list = ['alex', 'oldboy']
    return HttpResponse(json.dumps(user_list))

CBV知识点:给视图类添加装饰器

无法给单独的函数添加装饰器,必须加到 dispatch() 上,或者在类上加装饰器

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',
]

方式一:dispatch() 加装饰器

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

class StudentsView(View): 
    
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

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

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

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

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

方式二:类加装饰器

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

@method_decorator(csrf_exempt, name='dispatch')	# name表示只给dispatch加装饰器
class StudentsView(View): 
    
    def get(self, *args, **kwargs):
        return HttpResponse('GET')

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

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

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

总结

  • CBV 定义类的时候必须要继承 View
  • 在写 url 的时候必须要加 as_view()
  • 所有的方法本质上都是通过 dispatch 这个函数反射执行,如果想要在执行 getpost 方法前执行其他步骤,可以重写 dispatch
  • 添加装饰器前必须导入from django.utils.decorators import method_decorator
  • 添加装饰器的格式必须为 @method_decorator(),括号里面为装饰器的函数名
  • 给类添加是必须声明 name
  • 注意 csrf-token 装饰器的特殊性,它只能加在 dispatch 上面
posted @ 2019-02-21 21:32  湫兮  阅读(416)  评论(0编辑  收藏  举报