ModelForm
以已创建的model为原型创建表单时可以继承forms.ModelForm
大多数model的字段类型都有对应的form字段类型,除了几个比较特殊的字段
- ForeignKey这个model字段对应着form字段中的ModelChoiceField(其是一个ChoiceField)
- ManyToManyField字段则对应着form字段中的ModelMultipleChoiceField(其是一个MutipleChoiceField)
form字段中的一些其它属性:
- 如果在
model field
中blank=True
,在form field
中会有required=False
-
form field
的标签名将会默认为model field
中的verbose_name
-
model field
中的help_text
属性将会被form field
使用 - 如果
model field
中存在choices
参数,form field
中将会设置widget=Select
from django.db import models
from django.forms import ModelForm
TITLE_CHOICES = (
('MR', 'Mr.'),
('MRS', 'Mrs.'),
('MS', 'Ms.'),
)
class Author(models.Model):
name = models.CharField(max_length=100)
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
birth_date = models.DateField(blank=True, null=True)
def __str__(self): # __unicode__ on Python 2
return self.name
class Book(models.Model):
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
class AuthorForm(ModelForm):
# 在Meta中指定对应的model和会在表单中可见的字段
# 可以在Meta中重载error_messages
class Meta:
model = Author
fields = ['name', 'title', 'birth_date']
class BookForm(ModelForm):
class Meta:
model = Book
fields = ['name', 'authors']
上边的ModelForm基本上等同于下边自定义的Form(除了save()
方法)
from django import forms
class AuthorForm(forms.Form):
name = forms.CharField(max_length=100)
title = forms.CharField(
max_length=3,
widget=forms.Select(choices=TITLE_CHOICES),
)
birth_date = forms.DateField(required=False)
class BookForm(forms.Form):
name = forms.CharField(max_length=100)
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
save()方法
ModelForm中有一个save()
方法,该方法会将表单提交的数据保存到数据库中,并返回一个model实例
commit关键字参数
commit参数默认为True,即会自动将表单数据保存入数据库中;
若将commit设置为False,只会得到一个model实例,而不会向数据库提交,如果需要提交,则利用model实例的save()
方法进行提交;
需要注意的一点是,当model与其他Model存在many-to-many
关系时,若设置commit=False
,则在对model实例进行save()
后,还需要对表单调用save_m2m()
方法以提交many-to-many
表中的数据
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)
# Modify the author in some way.
>>> new_author.some_field = 'some_value'
# Save the new instance.
>>> new_author.save()
# Now, save the many-to-many data for the form.
>>> f.save_m2m()
选择使用的字段
官方推荐通过fields
来显式地指定需要提交的表单字段,以保证表单提交过程中的安全
设置field
属性的两种快捷方法
- 使用
__all__
来声明使用所有的字段from django.forms import ModelForm class AuthorForm(ModelForm): class Meta: model = Author fields = '__all__'
- 设置
exclude
属性来声明不会使用的字段class PartialAuthorForm(ModelForm): class Meta: model = Author exclude = ['title']
重载model中的字段
可以在ModelForm中改变model字段在表单中的表现形式
from django.forms import ModelForm, Textarea
from myapp.models import Author
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
# 将model中name列的表现形式由text变为textarea,并指定一些属性
widgets = {
'name': Textarea(attrs={'cols': 80, 'rows': 20}),
}
除此之外,还可以在Meta中重新指定label
, help_text
和error_messages
属性
from django.utils.translation import ugettext_lazy as _
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
# 通过字典来改变属性(键为需要改变的列名)
labels = {
'name': _('Writer'),
}
help_texts = {
'name': _('Some useful help text.'),
}
error_messages = {
'name': {
'max_length': _("This writer's name is too long."),
},
}
Form Asset
在Media中设置css
, js
等