在以前学习forms组件中,须要验证的项目是由咱们本身来写的,这里可使用ModleForm来把Modle自动转换为Form,这样就不用咱们本身写验证关系了html
############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创建一对多的关系,外键字段创建在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 与Author表创建多对多的关系,ManyToManyField能够建在两个模型中的任意一个,自动建立第三张表 authors=models.ManyToManyField(to='Author',) #在转换成表单后若是想要显示中文能够在括号内写上verbose_name="书籍名称"
############ModleForm############ from django.forms import ModelForm class BookModelForm(ModelForm): class Meta: model=Book fields="__all__"
#######这是在学习ModleForm以前本身写的form验证######## 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经过中间的写法把Modle转换为Form前端
views.py中
addBook:添加书籍git
def addbook(): if get请求: #实例化一个对象 form=BookModelForm() #把这个对象返回给前端页面,经过{{form.as_p}}渲染出来 return render(request,"addbook.html",locals()) # 标签渲染 {{form.as_p}} if post请求: form=BookModelForm(request.POST) if form.is_valid(): form.save() # create操做
editBook:编辑书籍django
def editbook(): if get请求: editbook=Book.objects.get(pk=id) #实例化对象中带有instance,此时渲染出的页面中是带值的,正好是编辑页面所需的效果 form=BookModelForm(instance=editbook) return render(request,"addbook.html",locals()) # 标签渲染 {{form.as_p}} if post请求: editbook=Book.objects.get(pk=id) form=BookModelForm(request.POST,instance=editbook) #有instance,此时form.save是更新操做 if form.is_valid(): form.save() # update操做
上面能够改为CBV的写法app
def get_modelForm(self): from django.forms import ModelForm class DemoModelForm(ModelForm): class Meta: model = self.model # 对全部字段进行处理 fields = "__all__" return DemoModelForm
调用的时候:ide
def add(self, request): #ModelFormDemo等同于获得了DemoModelForm这个类,所以下面要再加括号往里传数据 ModelFormDemo = self.get_modelForm() form = ModelFormDemo(request.POST)
把实例化出来的form循环看下里面是什么post
for i in form: print("i==>",i) #<input type="text" name="title" maxlength="32" required id="id_title" /> print("type(i)==>",type(i)) #<class 'django.forms.boundfield.BoundField'> #在BoundField类下面会发现有个field,在下面打印一下 print("i.field==>", i.field) #<django.forms.models.ModelMultipleChoiceField object at 0x0000015F8956B908> print(type(i.field)) <class 'django.forms.models.ModelMultipleChoiceField'> #.field属性咱们能够用来判断这个字段是否是一对多或多对多
获取app名字和关联表的名称学习
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==> <class 'app01.models.Book'>
咱们能够利用这个返回值
例如:
"pk": obj.pk,
"text": str(obj)ui
具体写法spa
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至关于作了筛选 option: UserInfo.objects.filter(depart__in=[1002,1003])
这个功能与ModelForm配合使用,告诉ModelForm在转换时怎么取option对象
models中:
class Customer(): gender_choices = ((1, '男'), (2, '女')) gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
问:如何在表中插入一条记录?
obj=Customer.objects.create(name="alex",gender=1)
问:想要获得这个对象所对应的这条记录性别是男仍是女?
print(obj.gender) #显然这样是不行的,只能获得1或2
固定写法,在字段名称前面加get_,后面加_dispaly()
obj.get_gender_displayi() #获得结果“男”,或“女”
1.ModleForm方便的地方不只在于能够自动把数据表中的字段构建为页面,还能够将前端传来的数据验证后直接进行保存,在之前咱们是本身从request.POST中get出页面传来的数据,而后再create到数据表中的。
2.form.save()操做包含create和update两种含义,其区别就在于ModelForm实例化的对象中有没有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()这类写法其实就是为了给ModleForm使用的,若是不使用ModleForm功能,那么写EmailField仍是CharField并无什么区别4.能够看出ModleForm功能很是适合构建添加和编辑页面