在之前學(xué)習(xí)forms組件中,需要驗(yàn)證的項(xiàng)目是由我們自己來(lái)寫的,這里可以使用ModleForm來(lái)把Modle自動(dòng)轉(zhuǎn)換為Form,這樣就不用我們自己寫驗(yàn)證關(guān)系了
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)長(zhǎng)泰免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000+企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
############models.py############
class Book(models.Model):
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)
# 與Publish建立一對(duì)多的關(guān)系,外鍵字段建立在多的一方
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
# 與Author表建立多對(duì)多的關(guān)系,ManyToManyField可以建在兩個(gè)模型中的任意一個(gè),自動(dòng)創(chuàng)建第三張表
authors=models.ManyToManyField(to='Author',)
#在轉(zhuǎn)換成表單后如果想要顯示中文可以在括號(hào)內(nèi)寫上verbose_name="書籍名稱"
############ModleForm############
from django.forms import ModelForm
class BookModelForm(ModelForm):
class Meta:
model=Book
fields="__all__"
#######這是在學(xué)習(xí)ModleForm之前自己寫的form驗(yàn)證########
class BookForm(forms.Form):
title=forms.CharField()
price=forms.DecimalField()
publishDate=forms.DateField()
#state=forms.ChoiceField(choices=[(1,"已出版"),(2,"未出版")])
#ModelChoiceField是單選
publish=forms.ModelChoiceField(queryset=Publish.objects.all())
#ModelMultipleChoiceField是多選
authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())
上面的示例中,ModleForm通過(guò)中間的寫法把Modle轉(zhuǎn)換為Form
views.py中
addBook:添加書籍
def addbook():
if get請(qǐng)求:
#實(shí)例化一個(gè)對(duì)象
form=BookModelForm()
#把這個(gè)對(duì)象返回給前端頁(yè)面,通過(guò){{form.as_p}}渲染出來(lái)
return render(request,"addbook.html",locals()) # 標(biāo)簽渲染 {{form.as_p}}
if post請(qǐng)求:
form=BookModelForm(request.POST)
if form.is_valid():
form.save() # create操作
editBook:編輯書籍
def editbook():
if get請(qǐng)求:
editbook=Book.objects.get(pk=id)
#實(shí)例化對(duì)象中帶有instance,此時(shí)渲染出的頁(yè)面中是帶值的,正好是編輯頁(yè)面所需的效果
form=BookModelForm(instance=editbook)
return render(request,"addbook.html",locals()) # 標(biāo)簽渲染 {{form.as_p}}
if post請(qǐng)求:
editbook=Book.objects.get(pk=id)
form=BookModelForm(request.POST,instance=editbook)
#有instance,此時(shí)form.save是更新操作
if form.is_valid():
form.save() # update操作
上面可以改成CBV的寫法
def get_modelForm(self):
from django.forms import ModelForm
class DemoModelForm(ModelForm):
class Meta:
model = self.model
# 對(duì)所有字段進(jìn)行處理
fields = "__all__"
return DemoModelForm
調(diào)用的時(shí)候:
def add(self, request):
#ModelFormDemo等同于得到了DemoModelForm這個(gè)類,因此下面要再加括號(hào)往里傳數(shù)據(jù)
ModelFormDemo = self.get_modelForm()
form = ModelFormDemo(request.POST)
把實(shí)例化出來(lái)的form循環(huán)看下里面是什么
for i in form:
print("i==>",i)
#
print("type(i)==>",type(i))
#
#在BoundField類下面會(huì)發(fā)現(xiàn)有個(gè)field,在下面打印一下
print("i.field==>", i.field)
#
print(type(i.field))
#.field屬性我們可以用來(lái)判斷這個(gè)字段是不是一對(duì)多或多對(duì)多
獲取app名字和關(guān)聯(lián)表的名稱
related_model_name = bfield.field.queryset.model._meta.model_name
related_app_lable = bfield.field.queryset.model._meta.app_label
obj = form.save()
print("obj==>", obj)
#obj==> Django 第二版
print("type==>", type(obj))
#type==>
我們可以利用這個(gè)返回值
例如:
"pk": obj.pk,
"text": str(obj)
具體寫法
teachers = models.ManyToManyField(verbose_name='任課老師', to='UserInfo',related_name="abc",limit_choices_to={"depart__in":[1002,1005]})
tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name='classes',limit_choices_to={"depart":1001})
渲染字段:
teachers: select
option: UserInfo.objects.all()
#加上limit_choices_to相當(dāng)于做了篩選
option: UserInfo.objects.filter(depart__in=[1002,1003])
這個(gè)功能與ModelForm配合使用,告訴ModelForm在轉(zhuǎn)換時(shí)怎么取option對(duì)象
models中:
class Customer():
gender_choices = ((1, '男'), (2, '女'))
gender = models.SmallIntegerField(verbose_name='性別', choices=gender_choices)
問(wèn):如何在表中插入一條記錄?
obj=Customer.objects.create(name="alex",gender=1)
問(wèn):想要得到這個(gè)對(duì)象所對(duì)應(yīng)的這條記錄性別是男還是女?
print(obj.gender) #顯然這樣是不行的,只能得到1或2
固定寫法,在字段名稱前面加get_,后面加_dispaly()
obj.get_gender_displayi() #得到結(jié)果“男”,或“女”
1.ModleForm方便的地方不僅在于可以自動(dòng)把數(shù)據(jù)表中的字段構(gòu)建為頁(yè)面,還可以將前端傳來(lái)的數(shù)據(jù)驗(yàn)證后直接進(jìn)行保存,在以前我們是自己從request.POST中g(shù)et出頁(yè)面?zhèn)鱽?lái)的數(shù)據(jù),然后再create到數(shù)據(jù)表中的。
2.form.save()操作包含create和update兩種含義,其區(qū)別就在于ModelForm實(shí)例化的對(duì)象中有沒(méi)有instance,有就是update
3.models中的字段類型
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField()
models.py中models.EmailField()這類寫法其實(shí)就是為了給ModleForm使用的,如果不使用ModleForm功能,那么寫EmailField還是CharField并沒(méi)有什么區(qū)別
4.可以看出ModleForm功能非常適合構(gòu)建添加和編輯頁(yè)面