文章目录
django自定义表单
两种方式
- 继承
Form
类 - 继承
ModelForm
类
python
from django import forms
from .models import Contact
# 自定义表单字段
class ContactForm1(forms.Form):
name = forms.CharField(label="Your Name", max_length=255)
email = forms.EmailField(label="Email address")
# 根据模型创建
class ContactForm2(forms.ModelForm):
class Meta:
model = Contact #指定表单与哪个Django模型相关联
fields = ('name', 'email',) #指定表单应该包含的模型字段
自定义错误信息
python
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(
required=True,
max_length=20,
min_length=6,
error_messages={
'required': '用户名不能为空',
'max_length': '用户名长度不得超过20个字符',
'min_length': '用户名长度不得少于6个字符',
}
)
password = forms.CharField(
required=True,
max_length=20,
min_length=6,
error_messages={
'required': '密码不能为空',
'max_length': '密码长度不得超过20个字符',
'min_length': '密码长度不得少于6个字符',
}
)
widgets
widgets
是表单和模型表单的一个属性,它允许你指定每个表单字段的HTML控件类型,以及它们的大小、样式等细节。
python
from django import forms
from myapp.models import Author
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
widgets = {
'name': forms.TextInput(attrs={'cols': 80}), # 使用 TextInput 并设置合适的宽度
'title': forms.TextInput(attrs={'cols': 50}), # 假设 title 也是单行文本
'birth_date': forms.DateInput(attrs={'type': 'date'}), # 使用 DateInput 来输入日期
}
labels = {
'name': 'Author Name', # 更具体的标签
'title': 'Title', # 为 title 字段设置标签
'birth_date': 'Birth Date', # 为 birth_date 字段设置标签
}
help_texts = {
'name': 'Enter the author\'s full name.', # 提供更具体的帮助文本
'title': 'Enter the author\'s title, if any.', # 提供 title 字段的帮助文本
'birth_date': 'Enter the author\'s birth date.', # 提供 birth_date 字段的帮助文本
}
error_messages = {
'name': {
'max_length': "The author's name is too long.", # 自定义错误消息
},
'title': {
'max_length': "The title is too long.", # 如果 title 字段有最大长度限制,添加自定义错误消息
},
'birth_date': {
'invalid': "Enter a valid birth date.", # 添加日期无效的错误消息
},
}
实例化和初始化
在定义完表单类后,要对其进行实例化和初始化。
python
form = ContactForm() #空表单
需要给表单设置初始数据,通过initial方法或设置
default_data:
python
# initial方法初始化
form = ContactForm(
initial={
'name': 'First and Last Name',
},)
# default_data默认值
default_data = {'name': 'John', 'email': 'someone@hotmail.com', }
form = ContactForm(default_data)
处理用户提交的数据
python
form = ContactForm(data=request.POST)
表示将使用请求对象 request
中的 POST
字典来填充表单
##给表单提供现有实例对象
在编辑或修改现有对象的场景中,可以使用Django的ModelForm
来提供现有对象的数据,而不是渲染一个空表单。
python
contact = get_object_or_404(Contact, pk=id) # 获取模型实例
form = ContactForm(instance = contact, data=request.POST) # 指定一个已经存在于数据库中的模型实例。当创建表单时,Django 会使用这个实例的当前数据来预填充表单字段。这样,当用户编辑一个对象并提交表单时,表单会显示该对象的当前值,而不是空字段。
显示一个指定的现有对象的值,用户提交表单后使用请求对象的POST来填充表单。
该方法仅适用于由模型创建的
ModelForm
,而不适用于自定义的表单。
验证表单
每个forms类可以通过clean
方法自定义表单验证。
python
def clean_username(self):
username = self.cleaned_data.get('username')
if len(username) < 6:
raise forms.ValidationError("Your username must be at least 6 characters long.")
elif len(username) > 50:
raise forms.ValidationError("Your username is too long.")
else:
user = User.objects.filter(username__exact=username).first()
if user.exists():
raise forms.ValidationError("Your username already exists.")
通用类试图使用表单
python
使用form_class
class View(FormView):
model = Article
form_class = ContactForm
template_name = ''
Formset
Formset
是一个用于处理一组表单的特殊对象。当你需要在单个页面上显示和处理多个相同类型的表单时,也就是处理表单中的表单时,Formset
非常有用。
而Formset的使用分为四步:
- 定义表单类
- 创建表单类
- 视图中实用表单集
- 在模板中渲染表单集
举个例子:
一个在线商店,商店允许顾客创建多个订单,每个订单包含多个商品。可以使用Django的Formset
来管理顾客添加到购物车的多个商品。
- 定义一个表单来收集顾客对每个商品的选择数量
python
from django import forms
class ProductForm(forms.Form):
quantity = forms.IntegerField(min_value=1, max_value=10, required=False, label='Quantity')
- 创建一个
Formset
来管理顾客添加到购物车的所有商品表单
python
from django.forms import formset_factory
ProductFormSet = formset_factory(ProductForm, extra=0, can_delete=True)
# extra=0表示初始时不显示额外的商品表单,顾客需要从商品列表中选择。
# can_delete=True允许顾客删除他们不再想要的商品。
- 视图函数中,你处理顾客的POST请求,创建
Formset
实例,并保存顾客选择的商品
python
formset = ProductFormSet(request.POST)
- 模板中,你需要渲染
Formset
并显示商品列表供顾客选择
python
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
<!-- 显示商品列表和顾客的选择 -->
<select name="{{ form.product.name }}" id="{{ form.product.id }}">
<option value="1">1</option>
<option value="2">2</option>
<!-- ...更多商品选项 -->
</select>
{% endfor %}
<input type="submit" value="Add to Cart">
</form>
本人也处于学习阶段,若有错误与不足请指出,关注DPT一起进步吧。