pin_drop当前位置:知识文库 ❯ 图文
Django Form表单详解 - 数据验证与ModelForm完整教程
目录
一、Form表单概述
Django Form是处理HTML表单的强大工具,集成了字段定义、数据验证、HTML生成和错误处理。Form类定义了表单字段和验证规则,可以自动生成HTML标签、验证用户输入、显示错误信息。
Django提供了两种表单类型:Form(手动定义字段)和ModelForm(从Model自动生成)。ModelForm直接从数据模型生成表单,大幅减少重复代码。
二、Form字段类型与参数
常用字段类型
常用字段参数
三、基本Form定义和使用
代码示例
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(
label='姓名',
max_length=100,
required=True,
error_messages={'required': '请输入姓名'}
)
email = forms.EmailField(
label='邮箱',
required=True,
error_messages={'invalid': '请输入有效的邮箱地址'}
)
subject = forms.CharField(label='主题', max_length=200)
message = forms.CharField(
label='留言',
widget=forms.Textarea(attrs={'rows': 5}),
required=True
)
# 使用示例
form = ContactForm(data={
'name': '张三',
'email': 'zhang@example.com',
'subject': '咨询',
'message': '你好',
})
if form.is_valid():
print(f"验证通过: {form.cleaned_data}")
else:
print(f"验证失败: {form.errors}")
输出结果:
代码示例
验证通过: {'name': '张三', 'email': 'zhang@example.com', 'subject': '咨询', 'message': '你好'}
四、ModelForm实战
ModelForm直接从Django Model生成表单,自动将模型字段映射为表单字段,支持form.save()直接保存数据到数据库。
代码示例
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'status', 'category']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}),
'status': forms.Select(attrs={'class': 'form-control'}),
}
labels = {
'title': '文章标题',
'content': '文章内容',
'status': '发布状态',
}
# 视图中使用
def article_create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.author = request.user
article.save()
return redirect('article_detail', pk=article.pk)
else:
form = ArticleForm()
return render(request, 'article_form.html', {'form': form})
ModelForm Meta选项
五、自定义验证
Django支持两种自定义验证方式:单字段验证(clean_)和多字段联合验证(clean())。
代码示例
from django import forms
from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
username = forms.CharField(label='用户名', min_length=3, max_length=20)
password = forms.CharField(
label='密码',
widget=forms.PasswordInput,
min_length=6
)
password_confirm = forms.CharField(
label='确认密码',
widget=forms.PasswordInput
)
email = forms.EmailField(label='邮箱')
def clean_username(self):
"""单字段验证"""
username = self.cleaned_data.get('username')
if not username.isalnum():
raise ValidationError('用户名只能包含字母和数字')
return username
def clean(self):
"""多字段联合验证"""
cleaned_data = super().clean()
password = cleaned_data.get('password')
password_confirm = cleaned_data.get('password_confirm')
if password and password_confirm and password != password_confirm:
raise ValidationError({'password_confirm': '两次密码不一致'})
return cleaned_data
六、Form与ModelForm对比
七、注意事项与最佳实践
注意:POST请求必须包含CSRF令牌,在模板中使用 {% csrf_token %} 标签生成隐藏字段,否则Django会拒绝请求。
注意:必须先调用
is_valid()方法后才能访问cleaned_data,否则会抛出异常。
注意:
clean_方法用于单字段验证,必须返回验证后的值。() clean()方法用于多字段联合验证。
小贴士
对于与数据库模型关联的表单(如文章发布、用户注册),优先使用ModelForm,可以大幅减少代码量。对于不直接关联模型的表单(如搜索、联系表单),使用普通Form更加灵活。
八、练习题
练习一
定义一个用户注册Form,包含用户名(3-20位字母数字)、密码(最少6位)、确认密码、邮箱字段。验证用户名只能包含字母和数字,并且两次密码必须一致。
练习二
为一个Article模型(包含title、content、status、category字段)创建ModelForm,在视图中实现文章的创建和编辑功能,编辑时需要加载已有数据到表单中。
常见问题
Form和ModelForm应该如何选择?
如果表单数据需要保存到数据库模型中,优先使用ModelForm,可以自动映射字段并支持save()方法。如果表单数据不关联模型(如搜索表单、联系表单),使用普通Form更加合适。
form.save(commit=False)的作用是什么?
commit=False会创建模型对象但不保存到数据库,允许在保存前修改对象属性(如设置author、created_at等)。修改完成后需要手动调用save()保存到数据库。
如何自定义表单字段的HTML样式?
使用widget参数的attrs属性来自定义HTML属性:widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入'})。也可以使用django-widget-tweaks第三方库在模板中修改。
如何在模板中渲染表单并显示错误信息?
使用{{ form.as_p }}可以自动渲染为段落格式,{{ form.as_table }}渲染为表格格式。手动渲染时,使用{{ form.field }}输出字段,{{ form.field.errors }}显示错误信息。
本文涉及AI创作
内容由AI创作,请仔细甄别