CBV与FBV

FBV

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

urls.pypython

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

views.pydjango

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

CBV

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

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

urls.pysession

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

views.pyapp

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 再返回给用户,因此看到的就是 GETpost

补充

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() 上,或者在类上加装饰器url

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 上面
相关文章
相关标签/搜索