九、django的form组件

在写django模板的表单内容时,有三种疑问:

  1. 每个输入框都要手写相当麻烦, 如何简便优化
  2. 用户的输入内容如何校验
  3. 校验出错了,又如何告知用户

而这些django的form组件都能很好的解决。

后端校验的重要性
因为前段页面内容展现在浏览器,用户随时可以通过浏览器控制台修改页面的前端内容。又或者遇上爬虫程序,直接绕过浏览器直接访问后端。所以后端程序必须设置内容校验,保护后端安全。

基本使用

首先要利用django的form组件为每一个表单都声明一个专属的类,除非表单的需要提交的内容完全相同

from django import forms

class MyForm(forms.Form):
	username = forms.CharField(min_length=3,max_length=8)
	password = forms.CharField(min_length=6,max_length=20)
	email = forms.EmailField()

上面是最基本的类声明例子,每一个类属性(也叫form字段)对应一个输入标签,forms.CharField()中的参数就是该字段(即该输入框的)的条件要求。

渲染标签

首先需要记住form组件只会渲染用户的输入标签(input select radio等),提交按钮还是要用户自己手写的。

下面通过一个例子来讲解form标签的渲染
视图层部分内容:

from django import forms

class RegForm(forms.Form):
    name=forms.CharField(max_length=8, label='用户名')
    pwd=forms.CharField(max_length=8,label='密码')
    email=forms.EmailField()


def register(request):
    form_obj=RegForm() #生成空的表单对象
    return  render(request,'app01/register.html',locals())

模板层部分内容:

<form action="" method="post">
    {% csrf_token %}
    {% for form_field in form_obj %}  
    <!-- 循环表单对象,从中获得的表单的字段对象-->
        <p>{{ form_field.label }}:{{ form_field }}</p>
	<!-- form_field.label表示该字段的label属性 -->
    {% endfor %}
    <input type="submit" value="注册">
</form>

渲染结果:
在这里插入图片描述
总结:

  • label属性默认渲染结果是在类中定义的该字段名首字母大写的形式, 也可以自定义直接给字段对象加label属性即可
  username = forms.CharField(min_length=3,label='用户名') 
  • 每个字段对象对应一个输入标签,默认是input标签,input表的name属性为该字段名,id属性为id_加字段名,带有required属性(表现必填)
  • 在声明类的时候可以在字段实例化中添加参数,大部分参数会作为input标签的属性渲染出来,例子中的username字段实例化时的参数max_length=8就被渲染在input标签内。

校验数据

校验数据的方法也简单,只需要用声明的表单类接收待校验的数据生成一个表单对象即可,校验的结果可以通过查看生成的表单对象。
注意待校验的数据需要组成字典的形式

form_obj = RegForm({'username':'jason','password':'123','email':'123'})

校验的流程:
依次拆分字典,以字典的key名等于对应表单类的字段名建立对应关系,然后以表单类中对该字段的声明条件来检查key的值。如果字典的key多于表单类的字段,不影响校验结果。

form_obj.is_valid() #获取校验结果
只要有字典中有一个键值对不合法,则校验结果为False,全部合法则为True

form_obj.cleaned_data #即使form_obj.is_valid()结果为False,字典中合法的数据仍能通过此方法可以找到

form_obj.errors #查看不符合条件的key以及原因

在pycharm中的Python console下测试:

from student.views import Myform
form_obj=Myform({'username':'pks','password':'ewq321','email':'ewq'})
form_obj.is_valid()
False
form_obj.cleaned_data
{'username': 'pks'}
form_obj.errors
{'pwd': ['This field is required.'], 'email': ['Enter a valid email address.']}
##注意看不合法的原因是以列表的形式出现

补充

  • forms类中所有的字段默认都是必填的
  • 校验的数据可以多传但是不能少传

展示不合法的原因

在上面校验数据的部分提到过form_obj.errors方法可以获取不合法的字段以及其不合法的原因,这里补充下表单对象的每个字段也有errors的方法,当该字段不合法时他能获取不合法的原因,如果字段合法errors便为空。
视图层增加对应POST请求

def reg(request):
    form_obj=Myform()
    if request.method == "POST":
        form_obj=Myform(request.POST)
        if form_obj.is_valid():
            return HttpResponse('注册成功')
    return render(request,'student/register.html',locals())

因此对模板稍作修改

<form action="" method="post">
    {% csrf_token %}
    {% for form_field in form_obj %}  
    <!-- 循环表单对象,从中获得的表单的字段对象-->
        <p>{{ form_field.label }}:{{ form_field }}</p>
		<!-- form_field.label表示该字段的label属性 -->
		<span>{{ form_field.errors.0 }}</span>
		<!-- 特别注意 form_field.errors一定要加0,不然会被渲染成ul形式,因为不合法的原因是以列表的形式-->
    {% endfor %}
    <input type="submit" value="注册">
</form>

errors获取的不合法的原因也是可以自定义,在你定义表单类的时候,就可以对每个字段设置一个特别的参数error_messages,该参数以字典的形式出现。字典的每个key必须对应字段设置的参数,key对应的值就是用来自定义不合法的原因。
对表单类修改,举例说明:

 username =forms.CharField(label='用户名',max_length=8,min_length=3,
                           error_messages={"required":"不能为空啊,兄弟",
                                           "min_length":"不能小于三位"
                                           }
                           )

效果展现如下
在这里插入图片描述
在这里插入图片描述

forms组件当你的数据不合法的情况下 会保存你上次的数据 让你基于之前的结果进行修改
但前提必备的条件是get请求和post请求传给html页面对象变量名表单对象必须一样

钩子函数

钩子函数在forms组件中就类似于第二道关卡,能够让我们在以字段定义的参数为条件校验成功后,再自定义一些校验条件

在forms组件中有两类钩子

  1. 局部钩子
    当你需要给单个字段增加校验规则的时候使用
  2. 全局钩子
    当你需要给多个字段增加校验规则的时候使用

实际案例

  1. 校验用户名中不能含有666 只是校验username字段 局部钩子

  2. 校验密码和确认密码是否一致 password confirm两个字段 全局钩子

钩子函数就是在类里面写方法

# 局部钩子
def clean_username(self):
    # 获取到用户名
    username = self.cleaned_data.get('username')
    if '666' in username:
        # 提示前端展示错误信息
        self.add_error('username','光喊666是不行滴~')
    # 将钩子函数钩去出来数据再放回去
    return username

# 全局钩子
def clean(self):
    password = self.cleaned_data.get('password')
    confirm_password = self.cleaned_data.get('confirm_password')
    if not confirm_password == password:
        self.add_error('confirm_password','两次密码不一致')
    # 将钩子函数钩出来数据再放回去
    return self.cleaned_data

表单类字段的其他参数

initial 默认值
required 控制字段是否必填
widget 为字段增加在前段页面渲染用的属性

widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'})
# 多个属性值的话 直接空格隔开即可

#validtors利用正则校验该字段

validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ]
# RegexValidator()中第一个参数为正则表达式,第二个参数用于定义不合法的原因
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值