zoukankan      html  css  js  c++  java
  • Django之Form组件

    一、Form组件介绍

    Form组件可以做的几件事情:

      1、用户请求数据验证

      2、自动生成错误信息    

      3、打包用户提交的正确信息

      4、如果其中有一个错误了,其他的正确,保留上次输入的内容

      5、自动创建input标签并可以设置样式

    Form组件的基本用法

     1  2     字段
     3     is_valid()
     4     cleaned_data
     5     errors
     6     字段参数:
     7         max_length
     8         min_length
     9         validators = [RegexValidators("xxx")]
    10         
    11     钩子函数
    12         clean_字段名
    13         注意:
    14             必须有返回值
    15             只能拿自己当前字段值
    16             raise ValidationError("xxx")
    17     下拉框数据源时时更新
    18         1、重写init方法
    19             先执行父类构造方法
    20             self.fields["xx"].choices = xxxxx
    21         2、ModelChoiceField

    二、Form组件的使用

    1、创建规则

    1 class Foo(Form): #必须继承
    2     username = xxx
    3     password = xxx
    4     email = xxx
    5 注意这里的字段必须和input的name字段一致

    2、数据和规则进行匹配

    先导入需要用到的模块

    from django.forms import Form
    from django.forms import fields
    from django.forms import widgets

    views.py

     1 from django.shortcuts import render,redirect
     2 from app01 import models
     3 # Create your views here.
     4 from django.forms import Form
     5 from django.forms import fields
     6 from django.forms import widgets
     7 # 1、创建规则
     8 class TeacherForm(Form):  #必须继承Form
     9     # 创建字段,本质上是正则表达式
    10     username = fields.CharField(
    11         required=True,     #必填字段
    12         error_messages={"required":"用户名不能为空!!"},  #显示中文错误提示
    13         widget=widgets.TextInput(attrs={"placeholder":"用户名","class":"form-control"})  #自动生成input框
    14        )
    15     password = fields.CharField(required=True, error_messages={'required': '密码不能为空'},
    16                                 widget=widgets.TextInput(attrs={'placeholder': '密码', 'class': 'form-control'}))  # 不能为空
    17     email = fields.EmailField(
    18         required=True,
    19         error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
    20         widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"})  # 自动生成input框
    21     ) #不能为空且邮箱格式要一致
    22 
    23 # 2、使用规则:将数据和规则进行匹配
    24 def teacherindex(request):
    25     teacher_obj = models.UserInfo.objects.all()
    26     # print(teacher_obj)
    27     return render(request,"teacherindex.html",{"teacher_obj":teacher_obj})
    28 def add(request):
    29     if request.method=="GET":
    30         form = TeacherForm()  #只是让显示一个input框
    31         return render(request,"add.html",{"form":form })
    32     else:
    33         form = TeacherForm(data=request.POST)
    34         # print(form)  #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
    35         if form.is_valid():# 开始验证
    36             # print('执行成功',form.cleaned_data)          # 所有匹配成功,字典
    37             # {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1}
    38             form.cleaned_data['ut_id'] = 1  #要分的清是班主任还是讲师
    39             models.UserInfo.objects.all().create(**form.cleaned_data)
    40             return redirect("/teacherindex/")
    41         else:
    42             # print("=====?",form.errors,type(form.errors))#返回失败的结果
    43             # print(form.errors["username"][0])   #拿到返回失败的结果,渲染到页面
    44             return render(request,"add.html",{"form":form})

    html

    {% block right %}
        <h1>添加老师信息</h1>
        <hr>
        <form method="post" novalidate>
            {% csrf_token %}
            <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }}
            <p>密码:{{ form.password }}</p>{{ form.errors.password.0 }}
            <p>邮箱:{{ form.email }}</p>{{ form.errors.email.0 }}
            <p><input type="submit" value="提交"></p>
        </form>
    {% endblock %}

    需要注意的几个点:

    1.如果访问视图的是一个GET 请求,它将创建一个空的表单实例并将它放置到要渲染的模板的上下文中。这是我们在第一个访问该URL 时会发生的情况。

    2.如果表单的提交使用POST 请求,那么视图将再次创建一个表单实例并使用请求中的数据填充它:form = NameForm(request.POST)。这叫做”绑定数据至表单“(它现在是一个绑定的表单)。

    3.我们调用表单的is_valid()方法;如果它不为True,我们将带着这个表单返回到模板。这时表单不再为空(未绑定),所以HTML 表单将用之前提交的数据填充,然后可以根据要求编辑并改正它。

    如果is_valid()True,我们将能够在cleaned_data 属性中找到所有合法的表单数据。在发送HTTP 重定向给浏览器告诉它下一步的去向之前,我们可以用这个数据来更新数据库或者做其它处理。

    4.

    form = TeacherForm()  #没有参数,只是一个input框

    form = TeacherForm(data=request.POST) # 数据和规则放置一起 (添加的时候用)

    form = TeacherForm(initial={'username':obj.username,'password':obj.password,'email':obj.email})   # 显示input,并且将数据库中的默认值填写到input框中 (编辑的时候用)

    Widgets

    每个表单字段都有一个对应的Widget 类,它对应一个HTML 表单Widget,例如<input type="text">

    在大部分情况下,字段都具有一个合理的默认Widget。例如,默认情况下,CharField 具有一个TextInput Widget,它在HTML 中生成一个<input type="text">

    局部钩子和全局钩子

    局部钩子

     1 from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
     2 def clean_name(self):
     3 
     4         val=self.cleaned_data.get("name")
     5 
     6         ret=UserInfo.objects.filter(name=val)
     7 
     8         if not ret:
     9             return val
    10         else:
    11             raise ValidationError("该用户已注册!")
    12 
    13     def clean_tel(self):
    14 
    15         val=self.cleaned_data.get("tel")
    16 
    17         if len(val)==11:
    18 
    19             return val
    20         else:
    21             raise  ValidationError("手机号格式错误")

    全局钩子

     1 def clean(self):
     2         pwd=self.cleaned_data.get('pwd')
     3         r_pwd=self.cleaned_data.get('r_pwd')
     4 
     5         if pwd and r_pwd:
     6             if pwd==r_pwd:
     7                 return self.cleaned_data
     8             else:
     9                 raise ValidationError('两次密码不一致')
    10         else:
    11 
    12             return self.cleaned_data

    字段的数据

    不管表单提交的是什么数据,一旦通过调用is_valid() 成功验证(is_valid() 返回True),验证后的表单数据将位于form.cleaned_data 字典中。这些数据已经为你转换好为Python 的类型。

    注:此时,你依然可以从request.POST 中直接访问到未验证的数据,但是访问验证后的数据更好一些。

    在上面的联系表单示例中,is_married将是一个布尔值。类似地,IntegerField 和FloatField 字段分别将值转换为Python 的int 和float

    第二种方式:

    创建字段,定义规则

     1 class TeacherForm(Form):  #必须继承Form
     2     # 创建字段,本质上是正则表达式
     3     username = fields.CharField(
     4         required=True,     #必填字段
     5         error_messages={"required":"用户名不能为空!!"},  #显示中文错误提示
     6         widget=widgets.TextInput(attrs={"placeholder":"用户名","class":"form-control"}),  #自动生成input框
     7         label="姓名",
     8         label_suffix=":"
     9        )
    10     password = fields.CharField(required=True, error_messages={'required': '密码不能为空'},
    11                                 widget=widgets.PasswordInput(attrs={'placeholder': '密码', 'class': 'form-control'}),
    12                                 label="密码",
    13                                 label_suffix=":"
    14       )  # 不能为空
    15 
    16     email = fields.EmailField(
    17         required=True,
    18         error_messages={"required":"邮箱不能为空!!","invalid":"无效的邮箱"},
    19         widget=widgets.EmailInput(attrs={"placeholder": "邮箱", "class": "form-control"}),  # 自动生成input框
    20         label = "邮箱",
    21         label_suffix = ":"
    22     ) #不能为空且邮箱格式要一致

    页面上渲染

    附上forms组件测试代码

    my_forms

     1 from django import forms
     2 
     3 from django.forms import widgets
     4 from app01.models import UserInfo
     5 
     6 from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
     7 
     8 class UserForm(forms.Form):
     9     name=forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
    10                          widget=widgets.TextInput(attrs={"class":"form-control"})
    11                          )
    12     pwd=forms.CharField(min_length=4,label="密码",
    13                         widget=widgets.PasswordInput(attrs={"class":"form-control"})
    14                         )
    15     r_pwd=forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
    16     email=forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
    17     tel=forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
    18 
    19 
    20     def clean_name(self):
    21 
    22         val=self.cleaned_data.get("name")
    23 
    24         ret=UserInfo.objects.filter(name=val)
    25 
    26         if not ret:
    27             return val
    28         else:
    29             raise ValidationError("该用户已注册!")
    30 
    31     def clean_tel(self):
    32 
    33         val=self.cleaned_data.get("tel")
    34 
    35         if len(val)==11:
    36 
    37             return val
    38         else:
    39             raise  ValidationError("手机号格式错误")
    40 
    41     def clean(self):
    42         pwd=self.cleaned_data.get('pwd')
    43         r_pwd=self.cleaned_data.get('r_pwd')
    44 
    45         if pwd and r_pwd:
    46             if pwd==r_pwd:
    47                 return self.cleaned_data
    48             else:
    49                 raise ValidationError('两次密码不一致')
    50         else:
    51 
    52             return self.cleaned_data
    53 
    54 myforms

    视图函数

     1 from django.shortcuts import render,HttpResponse
     2 
     3 # Create your views here.
     4 
     5 
     6 
     7 from app01.myforms import *
     8 
     9 
    10 def reg(request):
    11 
    12     if request.method=="POST":
    13 
    14         print(request.POST)
    15 
    16         #form=UserForm({"name":"yu","email":"123@qq.com","xxxx":"alex"})
    17 
    18 
    19         form=UserForm(request.POST) # form表单的name属性值应该与forms组件字段名称一致
    20 
    21         print(form.is_valid()) # 返回布尔值
    22 
    23         if form.is_valid():
    24             print(form.cleaned_data)  # {"name":"yuan","email":"123@qq.com"}
    25         else:
    26             print(form.cleaned_data)  # {"email":"123@qq.com"}
    27             # print(form.errors)        # {"name":[".........."]}
    28             # print(type(form.errors))  # ErrorDict
    29             # print(form.errors.get("name"))
    30             # print(type(form.errors.get("name")))    # ErrorList
    31             # print(form.errors.get("name")[0])
    32 
    33 
    34             #   全局钩子错误
    35             #print("error",form.errors.get("__all__")[0])
    36             errors=form.errors.get("__all__")
    37 
    38 
    39             return render(request,"reg.html",locals())
    40 
    41         '''
    42 
    43         form.is_valid()   :返回布尔值
    44         form.cleaned_data :{"name":"yuan","email":"123@qq.com"}
    45         form.errors       :{"name":[".........."]}
    46 
    47         '''
    48 
    49 
    50     form=UserForm()
    51 
    52     return render(request,"reg.html",locals())
    53 
    54 视图函数

    模板文件

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <style>
     7         .error{
     8             color: red;
     9         }
    10     </style>
    11     <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    12     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
    13     integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    14 </head>
    15 <body>
    16 
    17 <div class="container">
    18 
    19     <div class="row">
    20         <div class="col-md-6 col-lg-offset-3">
    21 
    22             {#<h3>简单form</h3>#}
    23             {##}
    24             {##}
    25             {#<form action="" method="post" novalidate>#}
    26             {#    {% csrf_token %}#}
    27             {#    <p>用户名<input type="text" name="name"></p>#}
    28             {#    <p>密码 <input type="text" name="pwd"></p>#}
    29             {#    <p>确认密码 <input type="text" name="r_pwd"></p>#}
    30             {#    <p>邮箱  <input type="text" name="email"></p>#}
    31             {#    <p>手机号 <input type="text" name="tel"></p>#}
    32             {#    <input type="submit">#}
    33             {##}
    34             {#</form>#}
    35 
    36             <hr>
    37             <h3>forms组件渲染方式1</h3>
    38             <form action="" method="post" novalidate>
    39 
    40                 {% csrf_token %}
    41                 <p>{{ form.name.label }}
    42                     {{ form.name }} <span class="pull-right error">{{ form.name.errors.0 }}</span>
    43                 </p>
    44                 <p>{{ form.pwd.label }}
    45                     {{ form.pwd }} <span class="pull-right error">{{ form.pwd.errors.0 }}</span>
    46                 </p>
    47                 <p>确认密码
    48                     {{ form.r_pwd }} <span class="pull-right error">{{ form.r_pwd.errors.0 }}</span><span class="pull-right error">{{ errors.0 }}</span>
    49                 </p>
    50                 <p>邮箱 {{ form.email }} <span class="pull-right error">{{ form.email.errors.0 }}</span></p>
    51                 <p>手机号 {{ form.tel }} <span class="pull-right error">{{ form.tel.errors.0 }}</span></p>
    52                 <input type="submit">
    53 
    54             </form>
    55 
    56             {#<h3>forms组件渲染方式2</h3>#}
    57             {##}
    58             {#<form action="" method="post" novalidate>#}
    59             {#     {% csrf_token %}#}
    60             {##}
    61             {#    {% for field in form %}#}
    62             {##}
    63             {#        <div>#}
    64             {#            <label for="">{{ field.label }}</label>#}
    65             {#            {{ field }}#}
    66             {#        </div>#}
    67             {##}
    68             {#    {% endfor %}#}
    69             {##}
    70             {#     <input type="submit">#}
    71             {#</form>#}
    72             {##}
    73             {#<h3>forms组件渲染方式3</h3>#}
    74             {##}
    75             {#<form action="" method="post">#}
    76             {#     {% csrf_token %}#}
    77             {##}
    78             {#     {{ form.as_p }}#}
    79             {##}
    80             {#     <input type="submit">#}
    81             {#</form>#}
    82 
    83 
    84         </div>
    85     </div>
    86 </div>
    87 
    88 </body>
    89 </html>
    90 
    91 模版文件
  • 相关阅读:
    jQuery easyUI 的combogrid进行模糊匹配
    SQL 快速生成不重复的卡号
    用SQL语句查找包含有某个关键字的存储过程、触发器、函数等等
    C# DateTime日期格式化
    【SQL触发器】类型 FOR 、AFTER、 Instead of
    【BAT】批量给制定类型的文件名添加前缀
    【VBA】将Excel数据转化为txt文本数据
    【Python】将多个工作簿中的数据按列合并到同一个工作表
    【Python】从DB2数据库中取出字段信息并根据字段类型生成SQL
    【Oracle】多行数据合并为一行,使用逗号分隔
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9664312.html
Copyright © 2011-2022 走看看