Django ModelForm
1. 依托模型创建表单 ---> ModelForm
如果你正在构建一个数据库驱动的应用程序,那么你很可能会有与Django模型密切相关的表单。
例如,你可能有一个BlogComment 模型,并且你想创建一个让人们提交评论的表单。
在这种情况下,在表单中定义字段类型是多余的,因为您已经定义了模型中的字段。
出于这个原因,Django提供了一个助手类,允许您Form 从Django模型创建一个类。
2. 字段类型
模型领域 表单字段
普通字段都相同
ForeignKey ModelChoiceField
ManyToManyField ModelMultipleChoiceField
TextField CharField 同 widget=forms.Textarea
ForeignKey和ManyToManyField模型字段类型是特殊情况:
ForeignKey由其代表django.forms.ModelChoiceField,ChoiceField其选择是一个模型QuerySet。
ManyToManyField由其代表 django.forms.ModelMultipleChoiceField,
MultipleChoiceField其选择是一个模型QuerySet。
3. 验证ModelForm
1. 验证表单
2. 验证模型实例
就像正常的表单验证一样,在调用is_valid()或访问 errors属性时显式地触发模型表单验证
4. 该save()方法
每个ModelForm都有一种save()方法。
此方法从绑定到表单的数据 创建并保存为数据库对象。
ModelForm 可以接受现有模型实例作为关键字参数的子类instance; 如果这个提供,save()将更新该实例。如果未提供, save()则将创建指定模型的新实例
如果提供实例,save()则是更新,如果不提供save(),则创建一个新实例
5. 选择要使用的字段
强烈建议您使用该fields属性明确设置应在表单中编辑的所有字段。
1. 将该fields属性设置为特殊值'__all__'以指示应该使用模型中的所有字段。
fields = '__all__'
2. 将内部类的exclude属性设置为从表单中排除的字段列表。
exclude = ['title']
3. 字段在表单中出现的顺序将是字段在模型中定义的顺序,ManyToManyField最后出现实例。
6. 覆盖默认字段
要为字段指定自定义小部件,请使用widgets内部Meta类的属性。这应该是字典映射字段名称到窗口小部件类或实例。
如果您希望CharFieldfor的name属性 Author由一个<textarea>而不是其默认值表示 ,则可以覆盖该字段的小部件
7. 启用字段的本地化
要为字段启用本地化,您可以使用该类的localized_fields 属性
class Meta:
model = Author
localized_fields = ('birth_date',)
如果localized_fields设置为特殊值'__all__',则所有字段都将被本地化
8. 表继承
与基本表单一样,您可以ModelForms通过继承它们来扩展和重用。如果您需要在父类中声明额外字段或额外方法以用于从模型导出的多个表单中,这非常有用。
class Meta 。子类如果存在,使用子类的,如果子类没有提供,使用父类的
9. 用指定窗体中使用的窗口小部件widgets
AuthorFormSet = modelformset_factory(
Author, fields=('name', 'title'),
widgets={'name': Textarea(attrs={'cols': 80, 'rows': 20})})
10. 在视图中使用模型框架
模型表单与表单集非常相似。假设我们想呈现一个表单来编辑Author模型实例:
from django.forms import modelformset_factory from django.shortcuts import render from myapp.models import Author def manage_authors(request): AuthorFormSet = modelformset_factory(Author, fields=('name', 'title')) if request.method == 'POST': # 使用用户填写的数据创建一个AuthorFormSet,用于校验用户的数据是否合法 formset = AuthorFormSet(request.POST, request.FILES) #如果输入校验合法 if formset.is_valid(): # 创建一条新纪录在数据库中 formset.save() # 其他操作 else: #如果是get请求,实例化一个AuthorFormSet() ModelForm对象 formset = AuthorFormSet() return render(request, 'manage_authors.html', {'formset': formset})