一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

views.py的文件中。

                                    CBV和FBV                                         

我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的。

就拿我们之前写过的添加班级为例:

FBV版:

python 终极篇 --- django 视图系统
# FBV版添加班级
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")
python 终极篇 --- django 视图系统

CBV版:

python 终极篇 --- django 视图系统
# CBV版添加班级
from django.views import View


class AddClass(View):

    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
python 终极篇 --- django 视图系统

注意:

使用CBV时,urls.py中也做对应的修改:

# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),

CBV简单的流程:
   1. AddPublisher.as_view() ——》 view函数
   2. 当请求到来的时候才执行view函数
     1. 实例化AddPublisher  ——》 self
     2. self.request = request
     3. 执行self.dispatch(request, *args, **kwargs)
      1. 判断请求方式是否被允许
       handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
       通过反射获取对应的方法
       GET  ——》  get
       POST ——》  post
      
     2. 执行获取到的方法  get(request,)  或者post(request,)
     3. 得到HttpResponse对象,返回给self.dispatch
    4. 得到HttpResponse对象,返回django处理

fbv ---   基于函数的视图    

cbv ----基于类的视图

                                 加装饰器                                     

fbv本身就是函数,所以与普通函数加装饰器没有任何区别;

cbv加装饰器

类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。

Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

python 终极篇 --- django 视图系统
# CBV版添加班级
from django.views import View
from django.utils.decorators import method_decorator

class AddClass(View):

    @method_decorator(wrapper)
    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
python 终极篇 --- django 视图系统
# 使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。

class Login(View):
     
    def dispatch(self, request, *args, **kwargs):
        print('before')
        obj = super(Login,self).dispatch(request, *args, **kwargs)
        print('after')
        return obj
 
    def get(self,request):
        return render(request,'login.html')
 
    def post(self,request):
        print(request.POST.get('user'))
        return HttpResponse('Login.post')
CBV扩展阅读

相关文章: