【Django】视图之FBV与CBV

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/")
      
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Al6n Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值