Django-ModleForm-创新互联

在之前学习forms组件中,需要验证的项目是由我们自己来写的,这里可以使用ModleForm来把Modle自动转换为Form,这样就不用我们自己写验证关系了

创新互联建站专注于阿克苏企业网站建设,响应式网站,商城网站定制开发。阿克苏网站建设公司,为阿克苏等地区提供建站服务。全流程按需搭建网站,专业设计,全程项目跟踪,创新互联建站专业和态度为您提供的服务

转换关系示例

############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:添加书籍

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:编辑书籍

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的写法

封装示例

def get_modelForm(self):
    from django.forms import ModelForm
    class DemoModelForm(ModelForm):
        class Meta:
            model = self.model
            # 对所有字段进行处理
            fields = "__all__"

    return DemoModelForm

调用的时候:

def add(self, request):
    #ModelFormDemo等同于得到了DemoModelForm这个类,因此下面要再加括号往里传数据
    ModelFormDemo = self.get_modelForm()
    form = ModelFormDemo(request.POST)

实例化出来的form里面有什么

把实例化出来的form循环看下里面是什么

for i in form:
    print("i==>",i)
    #
    print("type(i)==>",type(i))
    # 
    #在BoundField类下面会发现有个field,在下面打印一下
    print("i.field==>", i.field)
    #
    print(type(i.field))
    
    #.field属性我们可以用来判断这个字段是不是一对多或多对多

获取app名字和关联表的名称

related_model_name = bfield.field.queryset.model._meta.model_name
related_app_lable = bfield.field.queryset.model._meta.app_label

form.save()是有返回值的

obj = form.save()
print("obj==>", obj)
#obj==> Django 第二版
print("type==>", type(obj))
#type==> 

我们可以利用这个返回值
例如:
"pk": obj.pk,
"text": str(obj)

models中limit_choices_to的作用

具体写法

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对象

choices

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功能非常适合构建添加和编辑页面

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享标题:Django-ModleForm-创新互联
文章路径:http://myzitong.com/article/jiihc.html