1. 概述
Django的Form模型是处理用户请求最常用的方式之一。使用Form模型可以大大简化对表单数据的处理,验证,格式化和显示。
2. Form表单的定义
一个Django的Form表单是一个Python类,它的属性定义了表单中使用的字段。这些字段可以是文本/数字/日期等等。例如,以下是一个最简单的表单定义:
from django import forms
class SimpleForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
age = forms.IntegerField()
上面的代码定义了一个表单SimpleForm。它有三个字段,分别是name,email和age。这里的字段都是Django内置的Field类型,也可以自定义Field类型。
3. Form表单的渲染
3.1 渲染表单
渲染表单就是将表单内容转换为HTML表单元素的过程。Form对象提供了一个as_table()方法,让我们可以将表单渲染成默认的HTML表格形式,例如:
form = SimpleForm()
html_form = form.as_table()
print(html_form)
输出的HTML代码如下:
<table>
<tr><th><label for="id_name">Name:</label></th>
<td><input type="text" name="name" required id="id_name"></td></tr>
<tr><th><label for="id_email">Email:</label></th>
<td><input type="email" name="email" required id="id_email"></td></tr>
<tr><th><label for="id_age">Age:</label></th>
<td><input type="number" name="age" required id="id_age"></td></tr>
</table>
可以看到,表单以表格的形式呈现出来,每个表单控件都被放置在一个单独的行中。
3.2 渲染错误信息
当表单验证失败时,需要将错误信息呈现给用户。Form对象提供了一个非常有用的方法as_table(),它可以将表单及其错误信息一起呈现。例如:
from django.shortcuts import render
from .forms import SimpleForm
def some_view(request):
if request.method == 'POST':
form = SimpleForm(request.POST)
if form.is_valid():
# 做一些处理
pass
else:
form = SimpleForm()
return render(request, 'template_name.html', {'form': form})
下面是一个简单的模板代码,它会将表单及其错误信息一起呈现。
<form method="post">
{% csrf_token %}
{{ form.as_table }}
<input type="submit" value="Save">
</form>
如果表单提交失败,例如由于错误的输入,则可以通过{{ form.name.errors }}这样的方式来呈现该字段的错误信息。
4. Form表单的验证
在Django中,表单的验证是通过 Django Form Validation System 来完成的。在Form类中,我们可以定义以下方法来实现表单验证:
cleaned_data()
clean_fieldname()
clean(self)
4.1 cleaned_data()
当表单数据验证成功时,我们可以从表单对象中访问一个cleaned_data字典对象。该字典中包含了所有字段的数据,但格式已经经过验证和格式化。如下所示:
from django.shortcuts import render
from .forms import SimpleForm
def some_view(request):
if request.method == 'POST':
form = SimpleForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
age = form.cleaned_data['age']
# 做一些处理
pass
else:
form = SimpleForm()
return render(request, 'template_name.html', {'form': form})
可以看到,我们可以从表单对象的cleaned_data字典中获取验证后的字段数据。
4.2 clean_fieldname()
我们还可以通过实现一个名称为clean_fieldname()的函数来验证字段。例如,以下代码演示了如何验证name字段:
from django import forms
class SimpleForm(forms.Form):
name = forms.CharField()
def clean_name(self):
name = self.cleaned_data.get('name', '')
if len(name) < 5:
raise forms.ValidationError('Name is too short!')
return name
上面的代码实现了一个clean_name()函数,它将验证name字段。如果该字段包含的字符数量小于5,则会引发ValidationError异常。
4.3 clean()
除了验证字段外,我们还可以通过实现clean()函数来验证整个表单。例如:
from django import forms
class SimpleForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name', '')
email = cleaned_data.get('email', '')
if len(name) < 5 and '@' not in email:
raise forms.ValidationError('Name is too short and email is invalid!')
return cleaned_data
上面的代码实现了一个clean()函数,它将验证整个表单。一个有效的表单必须包含name和email两个字段,并且name字段长度必须大于等于5,email字段必须包含@字符,否则将引发ValidationError异常。
5. Form字段类型
在Django中,有很多内置的字段类型,可以满足大部分场景需要。如果内置字段不能满足需求,我们还可以自定义字段类型。
5.1 CharField
CharField是一个文本字段,它最基本的用法如下:
from django import forms
class SimpleForm(forms.Form):
first_name = forms.CharField(label='Your name', max_length=100)
CharField的标准参数:
label: 表单元素的标签文本
initial: 表单元素的默认文本
help_text: 表单元素下方的帮助文本
required: 指定该字段是否为必填项
disabled: 指定该字段是否禁用
5.2 EmailField
EmailField是一个文本字段,它用于验证email地址。使用方法如下:
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(label='Your name', max_length=100)
email = forms.EmailField(label='Your email')
message = forms.CharField(label='Your message', widget=forms.Textarea)
EmailField的标准参数和CharField一样。
5.3 DateField
DateField是一个日期字段,它用于处理日期数据。使用方法如下:
from django import forms
class ReservationForm(forms.Form):
name = forms.CharField(label='Your name', max_length=100)
email = forms.EmailField(label='Your email')
date = forms.DateField(label='Reservation date')
time = forms.TimeField(label='Reservation time')
DateField的标准参数:
input_formats: 可以使用的日期格式
widget: 可以指定使用哪个小部件,如下拉框或日历控件
5.4 IntegerField/FloatField
IntegerField和FloatField分别用于处理整型和浮点型数据。常见的用法如下:
from django import forms
class OrderForm(forms.Form):
item = forms.CharField(label='Item name', max_length=100)
quantity = forms.IntegerField(label='Quantity', initial=1)
price = forms.FloatField(label='Price')
5.5 CheckboxInput/RadioInput
CheckboxInput和RadioInput用于渲染复选框和单选框,常见的用法如下:
from django import forms
class PaymentForm(forms.Form):
payment_method = forms.ChoiceField(
label='Payment method',
widget=forms.RadioSelect,
choices=(('paypal', 'Paypal'), ('creditcard', 'Credit card'))
)
terms_accepted = forms.BooleanField(
label='I accept the terms and conditions',
widget=forms.CheckboxInput
)
CheckboxInput和RadioInput的标准参数:
attrs: 可以添加HTML属性到表单元素中
check_test: 指定验证复选框是否被选中的逻辑
5.6 ChoiceField/MultipleChoiceField
ChoiceField和MultipleChoiceField用于处理选择列表和多选列表。常见的用法如下:
from django import forms
class SurveyForm(forms.Form):
name = forms.CharField(label='Your name', max_length=100)
gender = forms.ChoiceField(
label='Gender',
choices=(('male', 'Male'), ('female', 'Female'), ('other', 'Other')),
widget=forms.RadioSelect
)
hobbies = forms.MultipleChoiceField(
label='Hobbies',
choices=(('reading', 'Reading'), ('running', 'Running'), ('swimming', 'Swimming')),
widget=forms.CheckboxSelectMultiple
)
ChoiceField和MultipleChoiceField的标准参数:
choices: 表示供用户选择的选项列表
coerce: 可以对用户提交的值进行处理,使其与指定的Python类型匹配
5.7 FileField
FileField用于处理文件上传。使用方法如下:
from django import forms
class UploadForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
FileField的标准参数:
max_length: 可以指定文件名的最大长度
allow_empty_file: 指定是否允许上传空文件
6. 自定义字段类型
如果内置的字段类型不能满足需求,我们可以通过继承Field类来定义自己的字段类型。通常,我们只需要实现to_python()和validate()两个方法。
6.1 继承Field类
from django.forms import Field
class MyField(Field):
def to_python(self, value):
"""
将传入的value类型转换为目标类型进行处理
"""
...
def validate(self, value):
"""
对传入的value进行验证
"""
...
6.2 to_python()
to_python()方法用于将提交表单时传入的数据转换为Python可用的类型。例如,如果我们需要一个字段用于处理复数类型,可以像下面这样实现to_python()方法:
class ComplexField(Field):
def to_python(self, value):
if isinstance(value, complex):
return value
try:
real, imag = value.split('+')
imag = imag.strip().replace('i', '')
return complex(float(real), float(imag))
except ValueError:
raise forms.ValidationError('Enter a valid complex number (e.g. "3+4i").')
6.3 validate()
validate()方法用于对转换后的值进行验证。例如,如果我们需要一个只包含正整数的字段,则可以通过以下方式来实现validate()方法:
class PositiveIntegerField(Field):
def to_python(self, value):
return int(value)
def validate(self, value):
super().validate(value)
if value <= 0:
raise forms.ValidationError('The number must be positive.')
7. 总结
在本文中,我们介绍了Django中Form表单的常用操作。我们可以了解到,Form表单是一个Python类,它的属性定义了表单中使用的字段。使用Form模型可以大大简化对表单数据的处理,验证,格式化和显示。我们还介绍了Form字段类型,包括CharField、EmailField、DateField、IntegerField/FloatField、CheckboxInput/RadioInput、ChoiceField/MultipleChoiceField和FileField等。如果内置的字段类型不能满足需求,我们可以自定义字段类型。总的来说,Django的Form模型为我们处理表单数据提供了很好的支持。