Django类视图

为什么要用类视图

Django使用函数视图可以完成所有的业务开发,但是维护困难,更不利于扩展,通过继承和复用构建自己的视图并且复用代码,这就是类视图产生的原因,尤其是python支持多继承,可组合继承多个类,极大方便于扩展。

以函数的方式定义的视图称为函数视图(function base view FBV),函数视图便于理解。但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳。

类视图(class base view CBV)

类视图的优点:代码可读性好、代码的复用性更高,如果其他地方需要用到类视图的某个特定逻辑,直接继承该类视图即可,而且可以重写父类的方法实现满足自己的业务需求。

类视图路由分发原理

路由配置

urlpatterns = [
    # 类视图(CBV)
    path('books/', views_class.BooksView.as_view())

]

http request请求到达路由之后,会交给views_class.BooksView.as_view()方法处理,看下这个方法的源码

复制代码
class View:
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in kwargs.items():
            setattr(self, key, value)

    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            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):
            self = cls(**initkwargs)
            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)
        view.view_class = cls
        view.view_initkwargs = initkwargs

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view
复制代码

可以看到as_view()方法最后返回了view方法的引用,也就是返回了view方法,在view方法里调用self.dispatch(request, *args, **kwargs)方法,进入该方法看下它的实现

复制代码
    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)
复制代码

如果请求方法名小写在self.http_method_names列表(八种http请求类型)里,那么拿到视图类中方法名==请求方法名小写的方法赋予handler,也就是说如果是get请求,该请求会被视图中名称为get方法拦截并处理。

 

本文作者:wang_longan

本文链接:https://www.cnblogs.com/longan-wang/p/15076970.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wang_longan  阅读(334)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起