Skip to content

Form层规范

概述

Form 层负责数据验证,使用 Django ModelForm 实现。每个模块的 forms.py 定义表单验证类,包含字段验证规则和中文错误提示。

设计原则

  • 继承 forms.ModelForm
  • 每个字段定义中文 error_messages
  • 使用 Meta.fields 指定验证字段
  • 验证在 Service 层 ORM 操作之前执行

完整示例

以案例模块为例,application/example/forms.py

python
from django import forms
from application.example import models


class ExampleForm(forms.ModelForm):
    """案例表单验证类"""

    # 案例名称
    name = forms.CharField(
        required=True,
        max_length=100,
        error_messages={
            'required': '案例名称不能为空',
            'max_length': '案例名称长度不得超过100个字符',
        }
    )

    # 案例图片
    avatar = forms.CharField(
        required=False,
        max_length=255,
        error_messages={
            'max_length': '案例图片长度不得超过255个字符',
        }
    )

    # 案例类型
    type = forms.IntegerField(
        required=True,
        min_value=1,
        max_value=4,
        error_messages={
            'required': '案例类型不能为空',
            'min_value': '案例类型值不能小于1',
            'max_value': '案例类型值不能大于4',
        }
    )

    # 案例状态
    status = forms.IntegerField(
        required=True,
        min_value=1,
        max_value=2,
        error_messages={
            'required': '案例状态不能为空',
            'min_value': '案例状态值不能小于1',
            'max_value': '案例状态值不能大于2',
        }
    )

    # 排序
    sort = forms.IntegerField(
        required=True,
        error_messages={
            'required': '排序不能为空',
        }
    )

    class Meta:
        model = models.Example
        fields = ['name', 'avatar', 'type', 'status', 'sort']

字段类型

Django 表单字段说明常用参数
CharField字符串max_length, min_length
IntegerField整数min_value, max_value
FloatField浮点数min_value, max_value
DecimalField精确小数max_digits, decimal_places
BooleanField布尔值-
DateTimeField日期时间input_formats
DateField日期input_formats
EmailField邮箱max_length
URLFieldURLmax_length

错误消息规范

每个字段必须定义中文 error_messages

python
name = forms.CharField(
    required=True,
    max_length=100,
    error_messages={
        'required': '案例名称不能为空',        # 必填验证
        'max_length': '案例名称长度不得超过100个字符',  # 长度验证
        'min_length': '案例名称长度不能少于2个字符',    # 最小长度
    }
)

type = forms.IntegerField(
    required=True,
    min_value=1,
    max_value=4,
    error_messages={
        'required': '案例类型不能为空',    # 必填验证
        'min_value': '案例类型值不能小于1',  # 最小值验证
        'max_value': '案例类型值不能大于4',  # 最大值验证
        'invalid': '案例类型格式不正确',    # 格式验证
    }
)

常用错误消息键

说明适用字段
required必填验证所有字段
max_length最大长度CharField
min_length最小长度CharField
max_value最大值IntegerField/FloatField
min_value最小值IntegerField/FloatField
invalid格式验证所有字段
unique唯一性验证需手动实现

Meta 类配置

python
class Meta:
    # 绑定模型
    model = models.Example

    # 指定验证字段(只验证以下字段)
    fields = ['name', 'avatar', 'type', 'status', 'sort']

    # 排除字段(不验证以下字段)
    # exclude = ['create_user', 'update_user']

fields vs exclude

  • fields:白名单,只验证列出的字段
  • exclude:黑名单,排除列出的字段
  • 推荐使用 fields,更明确

在 Service 中使用

python
from application.example import forms
from utils import R, regular

def add_example(request):
    """添加案例"""
    # 解析请求参数
    data, error = parse_request_body(request)
    if error:
        return R.failed(msg=error)

    # 表单验证
    form = forms.ExampleForm(data)
    if not form.is_valid():
        return R.failed(msg=regular.get_err(form))

    try:
        cleaned_data = form.cleaned_data
        # 使用 cleaned_data 创建记录
        Example.objects.create(
            name=cleaned_data.get('name'),
            type=cleaned_data.get('type'),
            status=cleaned_data.get('status'),
            sort=cleaned_data.get('sort'),
        )
        return R.ok(msg="创建成功")
    except Exception as e:
        return R.failed(msg="添加失败")

错误信息提取

使用 regular.get_err(form) 提取表单验证错误信息:

python
from utils import regular

form = forms.ExampleForm(data)
if not form.is_valid():
    error_msg = regular.get_err(form)  # 返回第一个错误的中文提示
    return R.failed(msg=error_msg)

自定义验证方法

python
class ExampleForm(forms.ModelForm):
    name = forms.CharField(required=True, max_length=100)

    def clean_name(self):
        """自定义验证:检查名称是否包含敏感词"""
        name = self.cleaned_data.get('name')
        if '敏感词' in name:
            raise forms.ValidationError('名称包含敏感词')
        return name

    def clean(self):
        """全局验证:检查字段间的关系"""
        cleaned_data = super().clean()
        start_date = cleaned_data.get('start_date')
        end_date = cleaned_data.get('end_date')
        if start_date and end_date and start_date > end_date:
            raise forms.ValidationError('开始日期不能晚于结束日期')
        return cleaned_data

总结

Form 层使用 Django ModelForm 实现数据验证,每个字段定义中文 error_messages。在 Service 层 ORM 操作之前执行验证,使用 regular.get_err(form) 提取错误信息。支持自定义验证方法(clean_{field})和全局验证(clean)。

小蚂蚁云团队 · 提供技术支持