您好,登錄后才能下訂單哦!
?
目錄
ModelForm.. 1
Model field與Form field:... 1
ModelForm save()方法:... 4
ModelForm Meta:... 5
ModelForm自定義驗證:... 5
ModelForm initial and ?instance:... 6
?
?
?
?
結合了form和model,將model的field類型映射成form的field類型,復用了model的驗證,還實現了存儲數據庫的簡單方法,寫更簡潔的代碼;
?
django提供一個輔助類(class Meta),使之可從Model創建Form;
生成的Form類中將具有和指定的模型字段對應的表單字段,順序為fields屬性中指定的順序;
?
?
每個模型字段有一個對應的默認表單字段,如模型中的ManyToManyField對應表單中的ModelMultipleChoiceField,ForeignKey<-->ModelChoiceField;
?
例:
mysite/books/models.py
TITLE_CHOICE = (
??? ('MR', 'Mr.'),
??? ('MRS', 'Mrs'),
??? ('MS', 'Ms.'),
)
?
class Author(models.Model):
??? name = models.CharField(max_length=100)
??? title = models.CharField(max_length=3, choice=TITLE_CHOICE)
??? birth_date = models.DateField(blank=True, null=True)
?
??? def __str__(self):
??????? return self.name
?
class Book(models.Model):
??? name = models.CharField(max_length=100)
??? authors = models.ManyToManyField(Author)
?
?
mysite/books/forms.py
from django import forms
from django.forms import ModelForm
from .models import Author, Book
?
class AuthorForm(ModelForm):
??? class Meta:
??????? model = Author
??????? fields = ['name', 'title', 'birth_date']?? #使用model的全部字段,用field = '__all__',另exclude = ('birth_date')排除的字段列表,建議顯式的設置,否則有安全問題
?
class BookForm(ModelForm):
??? class Meta:
??????? model = Book
??????? fields = ['name', 'authors']
?
# from .models import TITLE_CHOICE
# class AuthorForm(forms.Form):
#???? name = forms.CharField(max_length=100)
#???? title = forms.CharField(max_length=3, widget=forms.Select(choices=TITLE_CHOICE))
#???? birth_date = forms.DateField(required=False)
#
# class BookFrom(forms.Form):
#???? name = forms.CharField(max_length=100)
#???? authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
?
注:
模型字段blank=True,表單字段require=False;
模型字段verbose_name(首字段大寫the first character capitalized),表單字段label;
模型字段help_text,表單字段help_text;
模型字段choices,表單字段widget=forms.Select(choices=TITLE_CHOICE),choices從模型中來,選項通常會包含空選項,且默認會選擇,如果字段是必選的,它會強制用戶選擇一個選項,如果模型字段的default且有一個顯示default值,將不會包含空選項(初始值即blank=False);
?
?
這個方法根據表單綁定的數據創建并保存數據庫對象;
?
save()接受關鍵字參數commit,book=save(commit=False)時:
1將返回一個還沒有保存到數據庫的對象,這種情況下,要調用模型實例的form.save(),
2在多對多關系時指定commit=False,django不會立即為多對多有關系保存表單數據(只有實例在數據庫中存在時才可保存實例的多對多關系),要手動調用save_m2m()來保存多對多的表單數據
?
save_m2m()僅在save(commit=False)時才用到;
?
?
>>> from publish.models import Author,Book
>>> from publish.forms import AuthorForm,BookForm
>>> form = AuthorForm({'name':'jowin','title':'MR'})
>>> form.is_valid()
True
>>> form.is_bound
True
>>> form.save()?? #author=form.save(),后續用返回的對象
<Author: jowin>
?
>>> form = AuthorForm({'name':'mage','title':'MR'})
>>> form.is_valid()
True
>>> form.save()?? #author=form.save()
<Author: mage>
?
>>> authors = Author.objects.all()
>>> authors_id = [author.id for author in authors]
?
>>> form = BookForm({'name':'django book','authors':authors_id})
>>> form.is_valid()
True
>>> form.save()?? #book=form.save()
<Book: Book object>
?
>>> form = BookForm({'name':'py book','authors':authors_id})
>>> form.is_valid()
True
>>> form.save()
<Book: Book object>
?
>>> form = BookForm({'name':'js book','authors':authors_id})
>>> form
<BookForm bound=True, valid=Unknown, fields=(name;authors)>
>>> book = form.save(commit=False)
>>> book
<Book: Book object>
>>> book.name = 'react book'
>>> book.save()
?
>>> form.save_m2m()
>>> book.name
'react book'
?
?
?
mysite/publish/forms.py
class AuthorForm(ModelForm):
??? class Meta:
??????? model = Author
??????? fields = ['name', 'title', 'birth_date']?? #fields = '__all__';exclude = ('birth_date')
?
??????? labels = {'name': 'Writer'}
??????? widgets = {'name': Textarea(attrs={'cols': 80, 'rows': 20})}?? #forms.Textarea()
??????? help_texts = {'name': 'Some useful help text'}
??????? error_messages = {'name': {'max_length': "This writer's name is too long."}}
?
?
?
mysite/publish/forms.py
class AuthorForm(ModelForm):
??? class Meta:
??????? model = Author
??????? fields = ['name', 'title', 'birth_date']?? #fields = '__all__';exclude = ('birth_date')
?
??????? labels = {'name': 'Writer'}
??????? widgets = {'name': Textarea(attrs={'cols': 80, 'rows': 20})}
??????? help_texts = {'name': 'Some useful help text'}
??????? error_messages = {'name': {'max_length': "This writer's name is too long."}}
?
??????? def clean(self):
??????????? cleaned_data = super(AuthorForm, self).clean()
??????????? name = cleaned_data.get('name')
??????????? title = cleaned_data.get('title')
??????????? if len(name) < 40 and title == 'MR':
??????????????? raise ValidationError('Field: {} and {} is error'.format(name, title))
?
??????? def clean_name(self):?? #clean_<field-name>
??????????? name = self.cleaned_data['name']
??????????? if len(name) < 30:
??????????????? raise ValidationError('length must more than 30')
??????????? return name
?
?
提供初始值;
?
mysite/publish/views.py?? #view中使用modelform
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .forms import AuthorForm
from .models import Author
?
def index(request):
??? if request.method == 'POST':
???? ???form = AuthorForm(request.POST)
??????? if form.is_valid():
??????????? publish = form.save()
??????????? return HttpResponse('ok')
??? else:
??????? form = AuthorForm()
??? return render(request, 'publish/publish.html', {'form': form})
?
def update(request, publish_id):
??? author = get_object_or_404(Author, id=publish_id)
??? if request.method == 'POST':
??????? form = AuthorForm(request.POST, instance=author)?? #更新時要加instance,否則認為是新創建,也可form=AuthorForm(request.POST,initial={'name':'test'})
??????? if form.is_valid():
??????????? author = form.save()
??????????? return HttpResponse('add succeed')
??? form = AuthorForm(instance=author)?? #initial={'name':'test'}
??? return render(request, 'publish/publish.html', {'form': form})
?
?
?
mysite/publish/models.py
from django.db import models
?
TITLE_CHOICE = (
??? ('MR', 'Mr.'),
??? ('MRS', 'Mrs'),
??? ('MS', 'Ms.'),
)
?
class Author(models.Model):
??? name = models.CharField(max_length=100)
??? title = models.CharField(max_length=3, choices=TITLE_CHOICE)
??? birth_date = models.DateField(blank=True, null=True)
?
??? def __str__(self):
??????? return self.name
?
class Book(models.Model):
??? name = models.CharField(max_length=100)
??? authors = models.ManyToManyField(Author)
?
?
?
?
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。