【Django】视图之FBV与CBV

命运对每个人都是一样的,不一样的是各自的努力和付出不同,付出的越多,努力的越多,得到的回报也越多,在你累的时候请看一下身边比你成功却还比你更努力的人,这样,你就会更有动力。

导读:本篇文章讲解 【Django】视图之FBV与CBV,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

FBV

FBV(function base views) 就是在视图里使用函数处理请求。

  • 在urls.py定义路由

    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('user/', views.user), #定义请求路由
    ]
    
  • 在视图中处理请求

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    def user(request):
        #处理GET请求
        if request.method == 'GET':
            return HttpResponse('GET')
        
        # 处理POST请求
        if request.method == 'POST':
            return HttpResponse('POST')
    

CBV

CBV(class base views) 就是在视图里使用类处理请求,与FBV较大的不同点就是能够根据请求的的方法自己自动执行对应的方法。

  • 在urls.py定义路由

    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('user/', views.UserView.as_view()),
    ]
    
  • 在视图中处理请求

    from django.shortcuts import render,HttpResponse
    from django.views import View
    
    class UserView(View):
    
        def get(self,request,*args, **kwargs):
            # 获取数据
            return HttpResponse('GET')
    
        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')
    
        def patch(self,request,*args, **kwargs):
            # 更新局部数据,例如:用户信息的name这样的某几列
            return HttpResponse('patch')
    

CBV源码分析

路由 -> as_view方法 -> view方法 -> dispatch方法

  • as_view() – – – > view()

    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
       
             ...
    
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)
    
         ...
    
        return view
    

    url(r'^test/',views.UserView.as_view()), – – – > url(r'^test/',view) =》 这里就与FBV很相似了

  • dispatch()

    上面路由走的view方法,它返回的就是dispatch方法,这样实际上执行as_view方法得到的实际上就是dispatch方法的返回值。
    http_method_names = [‘get’, ‘post’, ‘put’, ‘patch’, ‘delete’, ‘head’, ‘options’, ‘trace’]

    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)  # 执行方法,拿到返回值,每个方法返回的结果是什么,就会得到什么
    

CBV的应用

  • 重写dispatch方法,实现在请求之前做些操作

    class UserView(View):
    
        def dispatch(self, request, *args, **kwargs):
            print('处理方法之前...')
            # 将方法执行的结果返回,两种调用父类的方式
            # ret = super(UserView, self).dispatch(request, *args, **kwargs)
            ret = super().dispatch(request, *args, **kwargs)
            print(ret)
            print('处理方法之后...')
            return ret
    
        def get(self,request,*args, **kwargs):
            #获取数据
            return HttpResponse('GET')
    
        def post(self,request,*args, **kwargs):
            #创建数据
            return HttpResponse('POST')
    
  • method_decorator装饰器给类的方法加装饰器

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

    • 方式一:给某个方法加上装饰器(此例给get方法加上)
      from django.views import View
      from django.utils.decorators import method_decorator
        
        
      class AddPublisher(View):  # CBV版
          @method_decorator(wrapper)
          def get(self, request):
              return render(request, "add_publisher.html")
        
          def post(self, request):
              pub_name = request.POST.get("name")
              models.Publisher.objects.create(name=pub_name)
              return redirect("/publisher_list/")
      
    • 方式二:加在dispatch方法上面,会给类下的所有方法加上此装饰器
      class AddPublisher(View):  # CBV版
          @method_decorator(wrapper)
          def dispatch(self, request, *args, **kwargs):
              obj = super(AddPublisher, self).dispatch(request, *args, **kwargs)
              return obj
        
          def get(self, request):
              return render(request, "add_publisher.html")
        
          def post(self, request):
              pub_name = request.POST.get("name")
              models.Publisher.objects.create(name=pub_name)
              return redirect("/publisher_list/")
      
    • 方式三:加在类上面
      @method_decorator(wrapper, name="post")
      @method_decorator(wrapper, name="get")  # 给哪个方法加,就要指定name
      class AddPublisher(View):  # CBV版
          def dispatch(self, request, *args, **kwargs):
              obj = super(AddPublisher, self).dispatch(request, *args, **kwargs)
              return obj
        
          def get(self, request):
              return render(request, "add_publisher.html")
        
          def post(self, request):
              pub_name = request.POST.get("name")
              models.Publisher.objects.create(name=pub_name)
              return redirect("/publisher_list/")
      

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/143952.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!