Django從models建立表單(forms)
= ModelForm
對於對映到model的表單,避免重複定義屬性,Django提供了一個幫助函式讓你從一個Model直接建立Form.
from django.forms import ModelForm
from myapp.models import Article
#建立一個表單類
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
# 建立一個表單用於新增文章
form = ArticleForm()
# 建立一個表單用於修改文章
article = Article.objects.get(pk=1)
form = ArticleForm(instance=article)
- 屬性型別
對映關係:
Model field=> Form field
AutoFieldNot represented in the form
BigIntegerFieldIntegerField with min_value set to -9223372036854775808 and max_value set to 9223372036854775807.
BooleanFieldBooleanField
CharFieldCharField with max_length set to the model field’s max_length
CommaSeparatedIntegerFieldCharField
DateFieldDateField
DateTimeFieldDateTimeField
DecimalFieldDecimalField
EmailFieldEmailField
FileFieldFileField
FilePathFieldFilePathField
FloatFieldFloatField
ForeignKeyModelChoiceField (see below)
ImageFieldImageField
IntegerFieldIntegerField
IPAddressFieldIPAddressField
GenericIPAddressFieldGenericIPAddressField
ManyToManyFieldModelMultipleChoiceField (see below)
NullBooleanFieldNullBooleanField
PositiveIntegerFieldIntegerField
PositiveSmallIntegerFieldIntegerField
SlugFieldSlugField
SmallIntegerFieldIntegerField
TextFieldCharField with widget=forms.Textarea
TimeFieldTimeField
URLFieldURLField
- 完整示例
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):
class Meta:
model = Author
fields = ['name', 'title', 'birth_date']
class BookForm(ModelForm):
class Meta:
model = Book
fields = ['name', 'authors']
等價於下面的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())
- 校驗一個ModelForm
主要有兩步:
1. 校驗form
2. 校驗model物件
Model Form校驗被顯示的觸發,在呼叫is_valid(),或訪問errors屬性和呼叫full_clean()時.
Model校驗在from校驗階段被觸發,在form的clean()方法被呼叫後。
# 重寫clean()方法
你可以重寫clean()方法,以提供額外的校驗。
繫結到一個model物件的model form包含一個instance屬性,用於訪問此特定物件。
# save()方法
>>> from myapp.models import Article
>>> from myapp.forms import ArticleForm
從POST資料建立一個例項
>>> f = ArticleForm(request.POST)
從form資料儲存一個新文章物件
>>> new_article = f.save()
建立一個表單編輯已經存在的文章,但使用POST資料來填充form
>>> a = Article.objects.get(pk=1)
>>> f = ArticleForm(request.POST, instance=a)
>>> f.save()