Django:CBV + FBV

FBV:function based view

视图函数,是指之前用的 views.py 中基于函数的开发,url 都是通过函数来实现的,每个 url 对应的函数之间都是独立的。

 直接在views.py 中,每个路径请求都是通过 def index(request):实现,如果遇到,请求的分支,通过 if 语句进行判断来处理

CBV:class based view

视图类:是指把有联系的函数放到同一个类中,类中是通过请求来进行分支的,

以登录为例进行简单介绍:

# urls.py

from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.LoginView.as_view())   # 重点 必须选中类后要 .as_view() 得到的是 小view函数对象
]

 # views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

from django.views import View   # 创建的来要继承该类

class LoginView(View):def get(self,request):
        print("GET....")
        return render(request,"login.html")

    def post(self,request):
        print("post.....")
        return HttpResponse("OK")

    def delete(self,request):
        pass

    def put(self,request):
        pass
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>


<form action="" method="post">
    {% csrf_token %}
    <input type="text" name="user">
    <input type="text" name="pwd">
    <input type="submit">
</form>

</body>
</html>
# login.html

CBV的使用

1、路径 url 的配置

  顾名知义,CBV就是通过类的方法来调用,我们在url中配置为如下路径

path('index/', views.LoginView.as_view())

  这里的LoginView是一个class 类,LoginView中的View不是必须的。一般约定成俗,会加一个View。要想使用此方法,这个路径后面还得必须有一个as_view(),这是必须的固定格式。

2、views.py里面的函数的格式

  在views里面配置类,需要导入一个模块View,并且使配置类继承它,如下代码:

from django.views import View
  # 这里必须要继承View这个类,只有继承了,对应url那里的as_view()才会有这个方法
  class UserView(View):
    def get(self, request):  # get请求时执行
      return HttpResponse('cbv-get')

    def post(self, request):
      return HttpResponse('cbv-post')   # post请求时执行

 

  注意:get和post的方法名,必须是小写。因为在源码中,使用了request.method.lower(),通过反射来找到类中的方法!详情请参考下面的内容

3、CBV 源码解析,匹配原理

  这里通过查看View的源码,可以看到里面会有很多种提交方法

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

  使用ajax的时候这些方法都是可以使用的。

  这种根据url来匹配方法的是通过反射方法(getattr)来做的。请求过来后先走dispatch这个方法,这个方法存在View类中。

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)
  request.method.lower()

  将请求方式变成小写。通过反射来找到类中对应的方法!

  所有的框架,本质都是通过请求方式,反射不同的函数!

  所以CBV的本质,实际还是用的FBV,只不过了类封装而已!

4、dispatch方法(重要)

  如果需要批量对方法(例如get,post等方法)做一些操作的时候,这里我们可以手动写一个dispatch,这个dispatch就和装饰器的效果一样。因为请求来的时候总是先走的dispatch,如下代码:

from django.views import View

  class LoginView(View):
    def dispatch(self, request, *args, **kwargs):
      print('操作前的代码...')
      obj = super(LoginView, self).dispatch(request, *args, **kwargs)
      print('操作后的代码...')
      return obj   # 这里一定要记得return

    def get(self, request)
      return render(request, 'login.html')  # 发送到login.html

    def post(self, request):
      return HttpResponse('cbv-post')

  这次我们再通过浏览器访问的时候,发现不管get或者post方法,都会走print代码。

  记住:dispatch方法是重写父类中的该方法

5、分析错误

  这是由于dispatch中没有返回值,才会报错。

from django.views import View

  class LoginView(View):
    def dispatch(self, request, *args, **kwargs):
      print('dispatch...')
      super().dispatch(request, *args, **kwargs)

    def get(self, request)
      print('get方法...')
      return HttpResponse('cbv-get')  

    def post(self, request):
      print('post方法...')
      return HttpResponse('cbv-post')
posted @ 2018-11-07 17:19  葡萄想柠檬  Views(136)  Comments(0Edit  收藏  举报
目录代码