DRF(1)Django的CBV

CBV(Class Base View)是类视图FBV(Func Base View)是函数视图

CBV简单使用

FBV小案例

from django.http import HttpResponse
from django.shortcuts import render


# Create your views here.

def book(request):
    if request.method == "GET":
        return HttpResponse("GET")
    elif request.method == "POST":
        return HttpResponse("POST")

CBV小案例

from django.views import View
from django.http import HttpResponse


class BookView(View):
    def get(self, response):
        return HttpResponse("View GET")

    def post(self, response):
        return HttpResponse("View POST")

CBV源码解析

这要从urls.py中讲起

from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path('func/', views.book),
    path('view/', views.BookView.as_view())  # 这行将路由和类绑定 其中最奇怪的是 as_view()
]

as_view()做了什么?

# 这个装饰器表示只允许类去调用
@classonlymethod
def as_view(cls, **initkwargs):  # 这里的cls就是我们的BookView
    """Main entry point for a request-response process."""
    for key in initkwargs:
        # 这边在检查 你使用的方法是否在合法的范围内 在View对象上方有写这个属性 
        # http_method_names = ["get","post","put","patch","delete","head","options","trace",]
        if key in cls.http_method_names:
            raise TypeError(
                "The method name %s is not accepted as a keyword argument "
                "to %s()." % (key, cls.__name__)
            )
        # 检测有没有定义对应的方法
        if not hasattr(cls, key):
            raise TypeError(
                "%s() received an invalid keyword %r. as_view "
                "only accepts arguments that are already "
                "attributes of the class." % (cls.__name__, key)
            )

    # 这是关键方法
    def view(request, *args, **kwargs):
        # 重申一遍 cls 是 BookView 所以这里实例化的self就是BookView
        self = cls(**initkwargs)
        # BookView 没有setup()方法所以来到了View中寻找
        """
            # 这里的self依然是 BookView 去做了一些数据绑定
            def setup(self, request, *args, **kwargs):
                if hasattr(self, "get") and not hasattr(self, "head"):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
        """
        self.setup(request, *args, **kwargs)
        # 如果没有 request 报错
        if not hasattr(self, "request"):
            raise AttributeError(
                "%s instance has no 'request' attribute. Did you override "
                "setup() and forget to call super()?" % cls.__name__
            )
        # 这里调用dispatch最后一步了
        """
            def dispatch(self, request, *args, **kwargs):
                # 他将我们的请求方法变成小写 又一次判断了是否合法
                if request.method.lower() in self.http_method_names:
                    # 这边做了一个反射 如用的是POST那么会转化成post然后判断self也就是BookView中有没有这个post方法
                    # 如果没有则赋值为http_method_not_allowed
                    handler = getattr(
                        self, request.method.lower(), self.http_method_not_allowed
                    )
                else:
                    handler = self.http_method_not_allowed
                # 返回handler 这个就变成了我们的post或者get方法,最终as_view也就返回了这个
                return handler(request, *args, **kwargs)
        """

        return self.dispatch(request, *args, **kwargs)

    view.view_class = cls
    view.view_initkwargs = initkwargs

    # __name__ and __qualname__ are intentionally left unchanged as
    # view_class should be used to robustly determine the name of the view
    # instead.
    view.__doc__ = cls.__doc__
    view.__module__ = cls.__module__
    view.__annotations__ = cls.dispatch.__annotations__
    # Copy possible attributes set by decorators, e.g. @csrf_exempt, from
    # the dispatch method.
    view.__dict__.update(cls.dispatch.__dict__)

    # Mark the callback if the view class is async.
    if cls.view_is_async:
        view._is_coroutine = asyncio.coroutines._is_coroutine

    # 最终其实就是返回了view的返回值dispath的返回值 也就是我们的get或者post等其他的函数
    return view
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值