第8章:Django表单(Forms)
8.1 表单基础
Form类定义
Django表单系统提供了一种强大且灵活的方式来处理HTML表单。表单类继承自django.forms.Form,用于定义表单字段和验证逻辑。
基本的表单类定义:
python
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
subject = forms.CharField(max_length=200)
message = forms.CharField(widget=forms.Textarea)表单字段类型
Django提供了多种内置表单字段类型,每种类型都有特定的验证规则:
python
from django import forms
from django.core.validators import RegexValidator
class ExampleForm(forms.Form):
# 字符串字段
name = forms.CharField(
max_length=100,
min_length=2,
label='姓名',
help_text='请输入您的真实姓名'
)
# 邮箱字段
email = forms.EmailField(
label='邮箱地址',
help_text='请输入有效的邮箱地址'
)
# 整数字段
age = forms.IntegerField(
min_value=0,
max_value=150,
label='年龄'
)
# 浮点数字段
salary = forms.FloatField(
min_value=0,
label='薪资'
)
# URL字段
website = forms.URLField(
required=False,
label='个人网站'
)
# 日期字段
birth_date = forms.DateField(
label='出生日期',
widget=forms.DateInput(attrs={'type': 'date'})
)
# 日期时间字段
appointment = forms.DateTimeField(
label='预约时间'
)
# 布尔字段
subscribe = forms.BooleanField(
required=False,
label='订阅邮件'
)
# 选择字段
GENDER_CHOICES = [
('male', '男'),
('female', '女'),
('other', '其他')
]
gender = forms.ChoiceField(
choices=GENDER_CHOICES,
label='性别'
)
# 多选字段
INTERESTS_CHOICES = [
('tech', '科技'),
('sports', '体育'),
('music', '音乐'),
('travel', '旅行')
]
interests = forms.MultipleChoiceField(
choices=INTERESTS_CHOICES,
widget=forms.CheckboxSelectMultiple,
label='兴趣爱好'
)
# 文件字段
avatar = forms.ImageField(
required=False,
label='头像'
)
# 自定义验证字段
phone = forms.CharField(
validators=[RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="请输入有效的手机号码"
)],
label='手机号码'
)表单验证
Django表单提供了多种验证机制:
- 字段级别的验证
- 表单级别的验证
- 自定义验证方法
python
from django import forms
from django.core.exceptions import ValidationError
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=150)
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
def clean_username(self):
"""验证用户名是否已存在"""
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise ValidationError("用户名已存在")
return username
def clean_email(self):
"""验证邮箱是否已存在"""
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError("邮箱已被注册")
return email
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("两次输入的密码不一致")
return cleaned_data表单渲染
Django提供了多种方式来渲染表单:
html
<!-- forms.py -->
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
subject = forms.CharField(max_length=200)
message = forms.CharField(widget=forms.Textarea)
<!-- views.py -->
from django.shortcuts import render
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# 处理表单数据
name = form.cleaned_data['name']
email = form.cleaned_data['email']
# 发送邮件等操作
return render(request, 'contact_success.html')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
<!-- contact.html -->
<form method="post">
{% csrf_token %}
<!-- 方式1:手动渲染每个字段 -->
<div>
<label for="{{ form.name.id_for_label }}">姓名:</label>
{{ form.name }}
{% if form.name.errors %}
<div class="error">{{ form.name.errors }}</div>
{% endif %}
</div>
<!-- 方式2:使用表单的as_p方法 -->
{{ form.as_p }}
<!-- 方式3:使用表单的as_table方法 -->
<table>
{{ form.as_table }}
</table>
<!-- 方式4:使用表单的as_ul方法 -->
<ul>
{{ form.as_ul }}
</ul>
<button type="submit">提交</button>
</form>
<!-- 方式5:循环渲染字段 -->
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<div class="error">
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
{% if field.help_text %}
<small class="help-text">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<button type="submit">提交</button>
</form>在模板中使用CSS类和属性:
python
# forms.py
class StyledForm(forms.Form):
name = forms.CharField(
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': '请输入姓名'
})
)
email = forms.EmailField(
widget=forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': '请输入邮箱'
})
)通过这种方式,你可以创建功能完整、验证完善的表单系统。
小结
Django表单基础是Web应用交互的核心:
- ✅ Form类定义表单结构和验证规则
- ✅ 多种字段类型满足不同数据需求
- ✅ 多层次验证机制确保数据有效性
- ✅ 灵活的表单渲染方式
- ✅ 与Bootstrap等CSS框架的良好集成
掌握表单基础是构建用户交互功能的前提。
下一篇
我们将学习ModelForm的使用。