• modelform组件以及ChoiceField属性


    一. Forms组件补充

    1.__init__()

    如果继承forms.Form的类中的每一个字段,或者大部分字段都做了相同的约束,可以将该约束放到__init__中编写

    实例:每一个字段都需要添加form-control类名

    1 class BookForm(forms.Form):
    2     title = forms.CharField(max_length=32)
    3     pub_date = forms.DateField()
    4     price = forms.DecimalField(max_digits=8, decimal_places=2)
    5 
    6     def __init__(self,*args,**kwargs):
    7         super().__init__(*args,**kwargs)
    8         for field in self.fields.values():
    9             field.widget.attrs.update({"class":"form-control"})

    2.ChoiceField属性,下拉菜单(元组套元组的形式)

    (1)choices作用:在数据库中用元组的第一项作为存储的值,在显示时,将元组的第二项作为显示的内容,便于前端使用下拉框

    :

    1 class Book(models.Model):
    2     id=models.AutoField(primary_key=True)
    3     title=models.CharField(max_length=32)
    4     gender=models.IntegerField(choices=((1,""),(2,"")),default=1)

    (2)与get_gender_display()方法同时使用,用来获取元组第二项的内容

    (3)在forms组件中渲染时,只需将类型改变成ChoiceField()

    :

    1 class BookForm(forms.Form):
    2     title = forms.CharField(label="书名",max_length=32)
    3     pub_date = forms.DateField(label="出版社")
    4     price = forms.DecimalField(label="价格",max_digits=8, decimal_places=2)
    5     gender=forms.ChoiceField(choices=((1,""),(2,"")))

    (4) Choices的问题:小元组的内容是固定的,无法随着数据库的更改二更改,不灵活

    3.ModelChoiceField属性

    作用:帮助渲染前端页面的下拉框

    优势:ModelChoiceField可以接收queryset属性的参数,内容可以随着数据库的更改而更改

    :

    1 class BookForm(forms.Form):
    2     title = forms.CharField(label="书名",max_length=32)
    3     gender=forms.ChoiceField(choices=((1,""),(2,"")))
    4     publish=forms.ModelChoiceField(queryset=Publish.objects.all())

    4.ModelMultipleChoiceField属性

    作用:帮助前端渲染页面的多选框,内容也能随着数据库的改变而改变

    :

    1 class BookForm(forms.Form):
    2     gender=forms.ChoiceField(choices=((1,""),(2,"")))
    3     publish=forms.ModelChoiceField(queryset=Publish.objects.all())
    4     author=forms.ModelMultipleChoiceField(queryset=Author.objects.all())

    二. modelForm组件

    1.作用:

      正常情况下的model和form是没有关系的,所有forms组件必须我们自己编写,但是ModelForm可以与model之间形成对应关系,这样就免去了我们自己写model

    2.语法:

    (1)需要先引入forms组件的model类:from django.forms import ModelForm

    (2)编写ModelForm类:

    1 class BookModelForm(forms.ModelForm):
    2     class Meta:
    3         model=Book  #与之关联的模型类
    4         # fields="__all__"  #可以渲染所有字段
    5         fields=["title","price"]  #可以渲染部分字段
    6 
    7         exclide=[“title”]  #可以渲染除某些字段外的所有字段

    (3)为公共字段或大多数字段添加内容,批量处理(添加__init__方法)

    Input标签的样式属性:

    1 def __init__(self,*args,**kwargs):
    2     super().__init__(*args,**kwargs)
    3     for field in self.fields.values():
    4         field.widget.attrs.update({"class":"form-control"})

    将错误转换成中文:

    1 def __init__(self,*args,**kwargs):
    2     super().__init__(*args,**kwargs)
    3     for field in self.fields.values():
    4         field.error_messages={"required":"不能为空"}

    (4)为单个字段添加内容(当每个字段的内容不同时)

     1 Labels方法:
     2 
     3 class BookModelForm(forms.ModelForm):
     4         class Meta:
     5             model=Book
     6             fields="__all__"
     7             labels={"title":"书籍名称","price":"价格"}
     8 
     9 error_messages方法:
    10 
    11 class BookModelForm(forms.ModelForm):
    12     class Meta:
    13         model=Book
    14         fields="__all__"
    15         error_messages={"title":{"required":"书籍名称不能为空"}}
    16 
    17 widgets字段:
    18 
    19 先引入:from django.forms import widgets as Fwidgets
    20 
    21 class BookModelForm(forms.ModelForm):
    22     class Meta:
    23         model=Book
    24         fields="__all__"
    25         widgets = {
    26             'pub_date': Fwidgets.Input(attrs={'type': 'date'})
    27         }

    3.forms组件有的接口,modelform也有,如is_valid,clean_data,errors

    除了forms组件有的接口外,modelform还有save方法

    Save方法会自动将干净的数据添加到表中,含有一对一,一对多,多对多的字段和表也会被处理好

    4.编辑页面,默认value值得做法:

    (1)取到待编辑的model对象

    :book_obj=Book.objects.fillter(id=1).first()

    (2)将model对象传入modelform

    :form=BookModelForm(request.POST,instance=book_obj)

    得到的form就是待前端页面渲染的对象

    结果:如果对ModelForm传了instance就相当于更新操作,没传instance,就相当于创建操作

    三.include

    作用:当某一段代码被重复利用的次数很多时,可以将其写到一个文件中,其他地方引用即可,减少代码的冗余性

    :在form.html中

     1 <form action="" method="post" novalidate>
     2     {% csrf_token %}
     3       {% for field in form %}
     4             <div class="form-group">
     5                  <label for="title">{{ field.label }}</label>
     6                  {{ field }}
     7                  <span>{{ field.errors.0 }}</span>
     8             </div>
     9      {% endfor %}
    10     <input type="submit" value="提交" class="btn btn-default pull-right">
    11 </form>

    在增加书籍页面中:

     1 <!DOCTYPE html>
     2 <html lang="zh-CN">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7      <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
     8     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
     9           integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    10 
    11 </head>
    12 <body>
    13 <h3>添加书籍</h3>
    14 <div class="container">
    15     <div class="row">
    16         <div class="col-md-6 col-md-offset-3">
    17            {% include 'form.html' %}  #代表将form.html中的代码放到这里
    18         </div>
    19     </div>
    20 </div>
    21 </body>
    22 </html>

    四.ModelForm的使用模板(做添加和编辑页面)

    1.在models.py中:正常写模型表

     1   class Book(models.Model):
     2      nid=models.AutoField(primary_key=True)
     3      title=models.CharField(max_length=32)
     4      price=models.DecimalField(max_digits=8,decimal_places=2) # 999999.99
     5      pub_date=models.DateTimeField()  # "2012-12-12"
     6      publish=models.ForeignKey(to="Publish",on_delete=models.CASCADE) 
     7      authors=models.ManyToManyField(to="Author")
     8 
     9 
    10    def __str__(self):
    11        return self.title

    2.在form.py中:构建ModelForm

     1 from django.forms import widgets as Fwidgets
     2 class BookModelForm(forms.ModelForm):
     3     class Meta:
     4         model=Book
     5         fields="__all__"
     6         labels={"title":"书籍名称","price":"价格"}
     7         widgets = {
     8             'pub_date': Fwidgets.Input(attrs={'type': 'date'})
     9         }
    10     def __init__(self,*args,**kwargs):
    11         super().__init__(*args,**kwargs)
    12         for field in self.fields.values():
    13             field.widget.attrs.update({"class":"form-control"})
    14             field.error_messages={"required":"不能为空"}
    15 
    16 等同于写了以下代码:
    17 
    18 class BookForm(forms.Form):
    19 
    20 
    21 title=forms.CharField(max_length=32)
    22 price=forms.IntegerField()
    23 pub_date=forms.DateField(widget=widgets.TextInput(attrs={"type":"date"}))
    24 #publish=forms.ChoiceField(choices=[(1,"AAA"),(2,"BBB")])
    25 publish=forms.ModelChoiceField(queryset=Publish.objects.all())
    26 authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())

    3.添加逻辑

     1 def add(request):
     2 
     3 if GET请求:
     4 
     5 form=BookModelForm()
     6 
     7 return render(request,{“form”:form})
     8 
     9 else POST请求:
    10 
    11 form=BookModelForm(request.POST)
    12 
    13 if form.is_valid():
    14 
    15 form.save()
    16 
    17 return render(“/”)
    18 
    19 else:
    20 
    21 return render(request,{“form”:form})

    4.编辑逻辑

     1 def edit(request,id):
     2 
     3 edit_obj=Book.objects.get(pk=id)
     4 
     5 if GET请求:
     6 
     7 form=BookModelForm(instance=edit_obj)
     8 
     9 return render(request,{“form”:form})
    10 
    11 else POST请求:
    12 
    13 form=BookModelForm(request.POST,instance=edit_obj)
    14 
    15 if form.is_valid():
    16 
    17 form.save()
    18 
    19 return rediecr(“/”)
    20 
    21 else:
    22 
    23 return render(request,{“form”:form})

    5.登录和编辑共同的渲染页面

     1 <form action="" method="post" novalidate>
     2 
     3 
     4 {% csrf_token %}
     5   {% for field in form %}
     6       <div class="form-group">
     7           <label for="title">{{ field.label }}</label>
     8           {{ field }}
     9           <span>{{ field.errors.0 }}</span>
    10       </div>
    11  {% endfor %}
    12 <input type="submit" value="提交" class="btn btn-default pull-right">
    13 
    14 
    15 </form>

     

  • 相关阅读:
    使用 RestSharp 调用 WebAPI 接口
    Android Studio 下载安装目录
    多线程之await/async
    ScriptX进行Web打印
    Sqlserver 查询最新修改过的表、过程和视图等
    SqlServer中的bit类型
    .Net 6
    PDA 使用总结
    SQL Server 发布订阅 发布类型详解
    Profile对象
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9914661.html
Copyright © 2020-2023  润新知