drf 前戏—CBV的使用及源码流程

Posted 紫青宝剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf 前戏—CBV的使用及源码流程相关的知识,希望对你有一定的参考价值。

drf 前戏—CBV的使用及源码流程

参考文献:https://www.cnblogs.com/wupeiqi/articles/7805382.html

视图:django的视图分为FBVCBV

反射的相关知识:https://www.cnblogs.com/Blogwj123/p/15828380.html

getattr(\'对象\',\'属性名\')

1.django的CBV

urlpatterns = [
    # path(\'admin/\', admin.site.urls),
    # path(\'index/\',views.index)
    path(\'index/\',views.Index.as_view())
]
from django.shortcuts import render
from django.views import View
from django.http.response import JsonResponse

# Create your views here.
def index(request):
    ret=\'msg\':\'hello world\'
    return JsonResponse(ret)

class Index(View):
    def get(self,request):
        ret = \'msg\': \'CBV hello world\'
        return JsonResponse(ret)

2.CBV源码

  • View中支持的请求方式

    # 源码中的支持方式,http的请求方式
    http_method_names = [\'get\', \'post\', \'put\', \'patch\', \'delete\', \'head\', \'options\', \'trace\']
    
  • 在django的路由系统中,一个路由对应一个函数;执行父类的:as_view()

    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            \'\'\'查看文件\'\'\'
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)# 实例化Index对象
            self.setup(request, *args, **kwargs)
            if not hasattr(self, \'request\'):
                raise AttributeError(
                    "%s instance has no \'request\' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            return self.dispatch(request, *args, **kwargs) #执行dispatch方法
        view.view_class = cls
        view.view_initkwargs = initkwargs
    
        update_wrapper(view, cls, updated=())
        update_wrapper(view, cls.dispatch, assigned=())
        return view #返回函数view
    

    说明:通过执as_view()每个视图函数都会执行dispatch()方法。

    def dispatch(self, request, *args, **kwargs):
        \'\'\'源码\'\'\'
        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)
    

3.扩展源码功能

说明:当子类没有方法时执行父类的,子类有值的时候执行子类(当前对象)的方法。

class Index(View):
    def dispatch(self, request, *args, **kwargs):
        return HttpResponse("dispatch") # 返回dispatch
    def get(self,request,*args,**kwargs):
        self.dispatch()
        ret = \'msg\': \'CBV hello world\'
        return JsonResponse(ret)

# Create your views here.
def index(request):
    ret=\'msg\':\'hello world\'
    if request.method==\'POST\':#request.method会把请求字母变化为大写
        pass
    return JsonResponse(ret)

class Index(View):
    def dispatch(self, request, *args, **kwargs):
        \'\'\'自定义dispatch\'\'\'
        func=getattr(self,request.method.lower())# self相当于对象。request.menthod获取当前请求的方式,使用反射
        ret=func(request,*args,**kwargs) # 加括号执行改函数,
        return ret
    def get(self,request,*args,**kwargs):
        # self.dispatch()
        ret = \'msg\': \'CBV hello world\'
        return JsonResponse(ret)

def dispatch(self, request, *args, **kwargs):
    print("执行前")
    ret=super(Index,self).dispatch(request, *args, **kwargs)
    print("执行后")
    return ret

from django.shortcuts import render,HttpResponse
from django.views import View
from django.http.response import JsonResponse


# Create your views here.

class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        print("执行前")
        ret=super(Index,self).dispatch(request, *args, **kwargs)
        # super()指当前对象父类,并不是某个类的父类,抽取出来可以供其他类的视图调用
        print("执行后")
        return ret

def index(request):
    ret=\'msg\':\'hello world\'
    if request.method==\'POST\':#request.method会把请求字母变化为大写
        pass
    return JsonResponse(ret)

class Index(MyBaseView,View):
    def get(self,request,*args,**kwargs):
        # self.dispatch()
        ret = \'msg\': \'CBV hello world\'
        return JsonResponse(ret)

class StudentView(MyBaseView,View):
    \'\'\'
    MyBaseView写在左边才会生效,因为View中存在默认的dispatch()方法。
    	面向对象中多继承左面优先(特殊情况下按照C3算法的进行继承)
    \'\'\'
    pass

4.使用django开发接口

  • 根据method不同做不同的操作;

4.1 基于FBV开发

urlpatterns = [
	re_path(r\'^order/\', views.order),
]
# 根据不同的请求方式完成不同的操作
def order(request):
    if request.method == \'GET\':
    	return HttpResponse(\'获取订单\')
    elif request.method == \'POST\':
    	return HttpResponse(\'创建订单\')
    elif request.method == \'PUT\':
    	return HttpResponse(\'更新订单\')
    elif request.method == \'DELETE\':
    	return HttpResponse(\'删除订单\')

4.2 基于CBV

urlpatterns = [
	re_path(r\'^order/\', views.OrderView.as_view()),
]
# 根据不同的请求方式完成不同的操作
class OrderView(View):
    def get(self,request,*args,**kwargs):
    	return HttpResponse(\'获取订单\')

    def post(self,request,*args,**kwargs):
    	return HttpResponse(\'创建订单\')

    def put(self,request,*args,**kwargs):
    	return HttpResponse(\'更新订单\')
    
    def delete(self,request,*args,**kwargs):
    	return HttpResponse(\'删除订单\')

说明:推荐使用CBV进行开发。

5.drf 引入

5.1 安装

pip install djangorestframework

5.2 介绍

  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为表征状态转移
  • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态;
  • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性;
  • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

继续努力,终成大器!

以上是关于drf 前戏—CBV的使用及源码流程的主要内容,如果未能解决你的问题,请参考以下文章

DRF之REST规范介绍及View请求流程分析

Django CBV流程及源码分析

drf的CBV流程

drf-CBV

drf之框架基础

drf框架与postman初始