Files
djangoadmin-wiki/DjangoAdmin_Django_EleVue/zh/volume7/form.md
T
2026-09-12 23:12:15 +08:00

227 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Form层规范
## 概述
Form 层负责数据验证,使用 Django `ModelForm` 实现。每个模块的 `forms.py` 定义表单验证类,包含字段验证规则和中文错误提示。
:::tip 设计原则
- 继承 `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` |
| `URLField` | URL | `max_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']
```
:::tip 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`)。