← 返回题目列表

Django Form 和 ModelForm 有什么用?和 DRF Serializer 有什么区别?

高频 中等 第 11 / 27 题 更新于 2026/07/31
DjangoFormModelFormSerializer

简化版

Django Form 用于表单数据校验和清洗,ModelForm 能根据 Model 自动生成字段并保存模型;DRF Serializer 更偏 API 场景,用于请求数据校验、对象序列化和反序列化。Form 面向 HTML 表单,Serializer 面向 REST API。

详细版

Form 的核心是 is_valid()cleaned_data 和错误收集。ModelForm 在此基础上绑定模型,减少重复字段定义。

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["name", "email"]

DRF Serializer 则把模型或普通对象转换成 JSON 友好的结构,也能把请求 JSON 校验后变成可保存数据。面试要说清:它们都能校验,但入口、输出和使用场景不同。

完整版教学

一、为什么需要 Form

用户输入永远不可信。HTML 表单提交过来的值都是字符串,还可能缺字段、乱填格式、绕过前端校验。Form 把字段声明、类型转换、校验错误统一起来。

request.POST -> Form -> is_valid -> cleaned_data/errors

这比在 view 里手写一堆 if 更可维护。

二、Form 的校验流程

Form 会先做字段级转换和校验,再执行 clean_<field>(),最后执行整体 clean()。通过后数据进入 cleaned_data

class LoginForm(forms.Form):
    username = forms.CharField(max_length=30)
    password = forms.CharField(min_length=8)
阶段作用
字段转换字符串转目标类型
字段校验必填、长度、格式
clean_xxx单字段业务校验
clean跨字段校验

三、ModelForm 的价值

ModelForm 根据 Model 字段生成表单,避免模型字段和表单字段写两遍。适合后台管理、CRUD 表单和简单业务录入。

form = UserForm(request.POST)
if form.is_valid():
    form.save()

但 ModelForm 不等于可以直接暴露所有字段。必须显式写 fieldsexclude,避免用户提交不该修改的字段,如 is_admin

ModelForm 最重要的安全习惯是显式列出允许用户提交的字段。

四、DRF Serializer 解决什么

API 场景里,请求体通常是 JSON,响应也要 JSON。Serializer 负责把复杂对象转成基础类型,也负责把输入数据校验成可用数据。

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "name", "email"]

Serializer 更关注 API 表达、嵌套对象、只读字段、响应输出和反序列化创建更新。

五、Form 和 Serializer 的对比

维度Form/ModelFormDRF Serializer
主要场景HTML 表单REST API
输入request.POSTJSON/body data
输出表单错误/cleaned_dataJSON/errors/validated_data
保存ModelForm.saveSerializer.save

如果项目是传统模板渲染,用 Form;如果是前后端分离 API,用 Serializer。

六、常见安全边界

不管 Form 还是 Serializer,都要避免让用户控制敏感字段。比如用户资料更新接口不能允许提交 roleis_staffbalance。输出也要避免泄露密码哈希、token 等字段。

输入白名单: 用户能改什么
输出白名单: 用户能看什么

这就是为什么输入模型和输出模型常常要分开。

七、常见误区与追问

  • 误区:前端校验了,后端 Form 可以省。 后端必须校验,前端可被绕过。
  • 误区:ModelForm 可以用 fields="__all__" 容易暴露敏感字段,生产中应谨慎。
  • 误区:Serializer 只负责输出 JSON。 它也负责输入校验和反序列化。
  • 追问:cleaned_data 和 data 区别? cleaned_data 是校验和转换后的可信数据。
  • 追问:跨字段校验放哪里? Form 的 clean() 或 Serializer 的 validate()
  • 追问:ModelForm 和 ModelSerializer 像吗? 思路类似,都能基于模型生成字段,但服务场景不同。
  • 追问:如何处理只读字段? Serializer 里用 read_only_fields 或显式字段配置。

八、加强记忆

Form 记成“HTML 表单校验器”,ModelForm 是“表单到模型的快捷桥”,DRF Serializer 是“API 输入输出契约”。它们都能校验,但服务对象不同。面试回答时抓住输入来源、输出形态、保存方式和字段白名单,就能说清边界。