Python Django怎么设计RESTful接口_继承DRF的ModelViewSet

酷伟酱_9320

酷伟酱_9320

2026-04-13

1048人浏览

原创

够用但需谨慎配置,modelviewset默认提供list、retrieve、create、update、destroy五个动作及标准路由,但实际需手动处理过滤、权限、字段控制、软删除等;必须显式定义get_queryset()和serializer_class,并在perform_create()中注入用户等后端字段。

python django怎么设计restful接口_继承drf的modelviewset

ModelViewSet 默认路由和动作是否真够用?

够用,但容易误以为“写个类就完事”。ModelViewSet 自带 list、retrieve、create、update、destroy 五个动作,对应标准 REST 路由(如 /api/users/ 和 /api/users/{id}/),但实际项目里常要:加搜索、过滤字段、控制返回字段、做权限校验、处理软删除、支持批量操作——这些都不是开箱即用的。

常见错误是直接继承 ModelViewSet 后啥也不重写,结果前端调 GET /api/orders/ 拿到全部订单(含敏感字段),或 POST /api/orders/ 不校验用户只能下自己的单。

  • 必须显式配置 queryset 和 serializer_class,漏写会报 AssertionError: 'View' should either include a `queryset` attribute...
  • get_queryset() 比直接写 queryset = Xxx.objects.all() 更安全,方便按请求动态过滤(比如只返回当前用户数据)
  • 别在 serializer_class 里硬编码 read_only_fields = ['created_at'],应改用 read_only_fields 或 extra_kwargs 控制字段级行为

怎么限制 list 返回的数据范围?

不能只靠前端传参数,后端必须拦截并约束。DRF 的 get_queryset() 是唯一可靠入口点。

例如用户只能看自己的订单:

def get_queryset(self):
    return Order.objects.filter(user=self.request.user)

如果还要支持管理员查看全部,就得加权限判断:

python-code-analyz
python-code-analyz

专业Python代码分析与优化,支持语法检查、安全扫描、性能评估、复杂度分析及重构后优化代码生成。

下载
  • 用 self.request.user.is_staff 判断角色,但更推荐用 DRF 的 has_permission 或自定义权限类
  • 避免在 get_queryset() 里写复杂条件链(如 .filter(a=...).filter(b=...).exclude(...)),先用变量存中间 queryset,提高可读性
  • 注意 select_related 和 prefetch_related 必须放 get_queryset() 里,否则序列化时 N+1 查询照常发生

如何让 create/update 避开字段篡改?

ModelViewSet 默认把所有字段都交给序列化器处理,而 ModelSerializer 默认允许所有模型字段写入——这是最大安全隐患。

正确做法是明确声明哪些字段可写、哪些由后端控制:

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ['id', 'items', 'status']
        read_only_fields = ['id', 'status']  # id 和 status 不允许客户端提交
        extra_kwargs = {
            'items': {'required': True},
        }
  • read_only_fields 只影响序列化输出,不影响反序列化输入;真正阻止字段被写入的是 extra_kwargs 中的 'write_only': True 或直接不列在 fields 里
  • 用户 ID、时间戳这类字段绝不能从 request.data 取,必须在 perform_create() 里注入:
    def perform_create(self, serializer):
        serializer.save(user=self.request.user, created_at=timezone.now())
    
  • 如果需要校验字段间逻辑(如 “结束时间不能早于开始时间”),必须在 Serializer 的 validate() 方法里做,而不是视图层

为什么 PATCH 请求有时 400 却没提示?

因为 DRF 默认对 partial update 做宽松校验,但某些字段(比如外键关联对象不存在)仍会静默失败,最终返回空响应或 400 + 无意义错误信息。

关键检查点:

  • 确认 URL 路径是否带尾部斜杠 —— Django 2.2+ 默认 APPEND_SLASH=True,但 DRF 路由若用 router.register() 生成,必须保证路径末尾有 /,否则 PATCH /api/orders/1(缺斜杠)会被重定向成 GET,导致方法错乱
  • 检查 serializer.is_valid(raise_exception=True) 是否启用;没启用时错误会吞掉,需手动 print serializer.errors
  • 外键字段提交字符串而非 ID(如 {"category": "electronics"})会直接 400,必须传整数 ID 或确保 CategorySerializer 支持 slug lookup(通过 lookup_field 和 to_internal_value)

真实项目里,ModelViewSet 看似省事,但每个动作背后都有隐式行为链。最易忽略的是:它不自动处理软删除、不区分「列表筛选」和「详情加载」的查询优化、也不隔离租户数据——这些都得手动补全,而且得在对的地方补。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python django

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1671

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4184

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1669

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

24237

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2967

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2987

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1163

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2323

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程