Form和ModelForm

Form和ModelForm

  • 进行数据校验,先看数据校验的过程
注册页面图解:
      前端为了用户体验会做一些校验,不满足校验要求会报错
      服务端也会对数据进行一些校验,不满足校验要求会报错
      数据库也会对数据进行一些校验,不满足校验要求会报错

      form组件和modleform组件就是让我们的数据校验过程更加简单一些,功能非常强大  

Forms组件

  • 提供了三个功能
1.能够帮我们生成HTML标签
      2.标签中保留之前用户输入的数据
      3.数据校验

forms组件的使用流程

  • 1.在views.py文件中创建一个自定义的form类
from django import forms   #需要先导入这个forms

      class RegisterForm(forms.Form):
            phone = forms.CharField()
            username = forms.CharField()
            password = forms.CharFied()

            #用label参数可以将HTML中的label标签中内容显示为中文
            phone = forms.CharField(label='手机号')
            username = forms.CharField(label='用户名')
            password = forms.CharField(label='密码')
  • 2.在views.py文件中写上视图函数
def register(request):
            if request.method == 'GET':
                  form = RegisterForm() #将上面的form类进行实例化
                  return render(request,'register.html',{'form':form})#将实例化后的对象返回到html中生成对应的属性的标签
  • 3.创建一个html文件,比如叫作register.html,内容如下
      <!DOCTYPE html>
      <html lang='en'>
      <head>
            <meta charset="UTF-8">
            <title>Title</title>
      </head>
      <body>

            <h1>注册页面</h1>
            <form action='/register/' method='post' novalidate> #novalidate取消浏览器自带的错误提示
                  {% csrf_token %}
            <div>
                  <!--{{ form.phone.id_for_label }}相当于绑定下面生成的input标签中的id属性  -->
                  <!-- {{ form.phone.label }}相当于把后台自定义的中文渲染到标签中  -->
                  <label for="{{ form.phone.id_for_label }}">{{ form.phone.label }}</label>
                  <!-- {{form.phone}}相当于生成这个input标签<input type="text" name="phone" required="" id="id_phone"> -->
                  {{ form.phone }}
            </div>

            <div>
                  <label for="{{ form.username.id_for_label }}">{{ form.username.label }}</label>
                  {{ form.username }}
            </div>

            <div>
                  <label for="{{ form.password.id_for_label }}">{{ form.password.label }}</label>
                  {{ form.password }}
            </div>

            <input type='submit'>
            </form>
      </body>
      </html>


保留原数据和校验功能

  • forms组件代码
      class RegisterForm(forms.Form):
            #每个字段,默认都有一个required=True的参数,表示该字段数据不能为空
            #phone = form.CharField(label='手机号',required=True)
            phone = forms.CharField(
                  label='手机号',
                  required=True,
                  #错误提示信息的自定制
                  error_messages={
                        'required':'小敏敏提示您,不能为空!',
                  }
            )
            username = forms.CharField(label='用户名')
            password = forms.CharField(label='密码')

  • views.py内容如下
      def register(request):
            if request.method == 'GET':
                  form = RegisterForm()
                  return render(request,'register.html',{'form':form})
            else:
                  print(request.POST)
                  form = RegisterForm(data=request.POST)
                  #把数据交给了RegisterForm,那么在通过form来渲染标签时,就将原来的的数据以默认值的形式(value='值')生成在了对应标签上
                  if form.is_valid(): #执行校验,如果所有数据都校验通过了,返回True,但凡有一个数据没有通过校验,返回False
                        print('通过校验的数据',form.cleaned_data)
                        return HttpResponse('ok')
                  print('错误信息>>>',form.errors)
                  return render(request,'register.html',{'form':form})
  • register.html内容
      <!DOCTYPE html>
      <html lang="en">
      <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <style>
                  <!-- 给错误信息定制一些css样式 -->
                  .error_msg{
                        font-size:12px;
                        color:red;
                  }
            </style>
      </head>
      <body>

      <h1>注册页面</h1>
      <!-- form标签的这个novalidate属性,就是把浏览器自带的必填提示信息去掉 -->
      <form action='/register/' method='post' novalidate>
            {% csrf_token %}
         <!--   {{ form.errors }} 表示存放着所有字段的错误信息 -->
      <div>
            <label for='{{ form.phone.id_for_label }}'>{{ form.phone.label }}</label>
            {{ form.phone }}
            <!-- form.phone.errors.0 表示展示一个错误信息  -->
            <span class='error_msg'>{{ form.phone.errors.0 }}</span>
       </div>

      <div>
            <label for='{{ form.username.id_for_label }}'>{{ form.username.label }}</label>
            {{ form.username }}
            <span class="error_msg">{{ form.username.errors.0 }}</span>
      </div>

      <div>
            <label for='{{ form.password.id_for_label }}'>{{ form.password.label }}</label>
            {{ form.password }}
            <span class='error_msg'>{{ form.password.errors.0 }}</span>
      </div>

      <input type='submit'>

      </body>
      </html>

Form常用字段属性与插件

  • initial 初始值
#生成input标签有个默认值
      username = fomrs.CharField(label='用户名',initial='小红')
  • widget 插件的意思,能够定制我们的标签显示效果
示例1  密文输入框
      password = forms.CharField(
            label='密码',
            #CharField默认插件是TextInput相当于type='text',下面相当于修改type='password',完整写法forms.widgets.PasswordInput,下面是简写
            widget = forms.PasswordInput,
            )

      示例2 给标签加上一些其他属性
      password = forms.CharField(
            label='密码',
            #attrs={'标签属性':'属性值'}
            widget=forms.PasswordInput(attrs={'class':'c1 c2','placeholder':'请输入密码'}),
            )
  • 生成单选下拉框 ChoiceField默认插件是widget=forms.Select
#sex=forms.fields.ChoiceField() fields可以不用写
sex = forms.ChoiceField(
            choices=((1,'女'),(2,'男')),
            
            #(1,'女')生成一个option标签,value值为1,文本内容为女
			label='性别',
            initial =2,#初始值
            )

  • 单选radio框 widget=forms.RadioSelect
sex = forms.ChoiceField(
            choices=((1,'女'),(2,'男')),
            label='性别',
            #initial =2,
            #widget=forms.Select,  #ChoiceField的默认插件
            #input,type='radio'的单选框
            #widget=forms.RadioSelect,
            #修改插件,并设置属性
            widget=forms.RadioSelect(attrs={'class':'c1'})
            )
  • 多选下拉框 MultipleChoiceField
hobby = forms.MultipleChoiceField(
            choices=((1,'喝酒'),(2,'抽烟'),(3,'励志')),
            label='爱好'
            )
  • 多选checkbox框 widget=forms.CheckboxSelectMultiple
hobby = forms.MultipleChoiceField(
            choices=((1,'喝酒'),(2,'抽烟'),(3,'励志')),
            label = '爱好',
            #widget=forms.CheckboxInput, #做单选功能的复(多)选框形式,必须勾选协议的那个选框
            widget=forms.CheckboxSelectMultiple,
            )
  • 单选功能的复选框形式,像那种勾选同意协议的那个选框 widget=forms.CheckboxInput 里面choices只有true或false
status = forms.MultipleChoiceField(
            choices=(('True',同意),('Flase',不同意))
            label='同意是否勾选协议',
            widget=forms.CheckboxInput,
            )

  • date类型
 bday = forms.CharField(
            label='生日',
            widget=forms.TextInput(attrs={'type':'date'}),  只要设置一个date属性就可以了
            )

单选或多选框使用数据库中的数据

  • 方式1 forms.ModelChoiceField
      models中的模型类
      class Publish(models.Model):
            name = models.CharField(max_length=32)
      
            def __str__(self):
                  return self.name

      form类中的字段写法
      #生成选择框,并使用数据库中的数据  必须要用这个ModelChoiceField
      publish = forms.ModelChoiceField(
            queryset=models.Publish.objects.all(),  #必须是queryset
            )
      会自动生成单选下拉框,并且option标签value属性对应的值,是queryset参数对应的queryset集合里面的models模型类对象的id值,option标签的文本内容是每个models模型类对象。
      #生成标签的时候,页面显示第一层会有个自带的'--------',第二个往后才是数据


  • 方式2 forms.ChoiceField
publish = forms.ChoiceField(
            choices=models.Publish.objects.all().values_list('id','name')
      #quertset[(1,'xx出版社'),]
            )
      #生成标签的时候,没有上面那个自带的'--------',直接就显示的是数据
posted @ 2023-05-27 05:09  布衣梦蝶1978  阅读(38)  评论(0编辑  收藏  举报