You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中viewsets.ViewSet与ModelViewSet的适用场景、差异及方法重写疑问

Django REST Framework 3.7: ViewSet vs ModelViewSet 差异、适用场景及get_object()重写问题

嘿,刚好对DRF 3.7里这两个ViewSet的区别熟得很,我来给你掰扯清楚:

一、ViewSet与ModelViewSet的核心差异

最本质的区别在于默认提供的功能多少和继承链不同:

  • viewsets.ViewSet:它的父类是APIView,仅提供将视图方法(比如list、create)绑定到路由的能力,但没有任何默认的CRUD动作实现。你得手动编写每个动作的逻辑,或者按需混入对应的Mixin(比如ListModelMixin、CreateModelMixin)来添加特定功能。
  • viewsets.ModelViewSet:它继承自GenericViewSet,同时混入了CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin、ListModelMixin这五个Mixin。这意味着它自带了完整的list、create、retrieve、update、partial_update、destroy动作实现,只要指定queryset和serializer_class,就能直接跑出一套标准的CRUD接口,不用自己写基础逻辑。

二、分别何时使用?

用ModelViewSet的场景:

当你的视图逻辑完全对应单个模型的标准CRUD操作,不需要太多自定义逻辑时,它能帮你省超多代码:

  • 简单的资源管理接口(比如用户信息、商品列表、分类管理)
  • 快速搭建原型,只需要基础的增删改查功能
  • 业务逻辑不复杂,不需要对某个CRUD动作做特殊处理的场景

用ViewSet的场景:

当你需要灵活自定义视图功能时,它是更好的选择:

  • 只需要部分CRUD动作(比如只需要retrieve和list,不需要创建、修改、删除),可以只混入对应的Mixin(比如RetrieveModelMixin+ListModelMixin)
  • 需要添加非CRUD的自定义动作(比如批量导入数据、发送验证码、生成统计报表),可以自己定义方法并用@action装饰器标记
  • 视图逻辑不依赖单个模型(比如跨多个模型的复杂查询、非数据库相关的操作)

三、关于get_object()方法的重写问题

先纠正个小细节:DRF里的方法是get_object()(单数),不是get_objects()。

  • 对于viewsets.ViewSet:它本身继承自APIView,默认没有get_object()方法,所以不存在“重写”的说法。如果需要类似功能,你要么自己实现这个方法,要么改为继承viewsets.GenericViewSet(它包含get_object()),再按需混入Mixin。
  • 对于viewsets.ModelViewSet:它继承了GenericViewSet,而get_object()正是GenericViewSet提供的方法,所以你完全可以重写它来自定义获取对象的逻辑,比如:
    def get_object(self):
        obj = super().get_object()
        # 自定义逻辑:验证当前用户是否有权限访问该对象
        if obj.owner != self.request.user:
            raise PermissionDenied()
        return obj
    

内容的提问来源于stack exchange,提问作者giveJob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:55:28