form介绍

用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端。

在给后端提交数据的时候,我们常常也需要对于用户输入的数据进行一个及时的校验,提示用户格式或者内容是否输入错误;如果出现错误,就需要个用户进行一个提示。

在django中,forms组件就实现了这一功能!主要功能如下:

  • 生成页面可用的html标签
  • 对用户提交的数据进行校验
  • 保留上次内容并提示用户

1. 什么是forms组件

forms组件其实是django里的一个模块。

2. 为什么要使用forms组件

其实使用forms组件,有一个原因是因为它提供了三大功能(见上面);

另一方面,我们会问:“对用户进行校验,然后保留上次内容并提示用户的功能后端也可以做,那么为什么还要引入forms组件呢?”

因为forms组件校验和后端校验其实组成了一个双重校验!为什么这么说呢?我们来举一个小例子:当我们在某购物平台购买商品时,选好了商品,前端会计算出一个价格(这其实就是前端的首次校验),然后提交给后端(这里的前端校验其实是弱不禁风的,很容易被人为的进行修改),如果后端不进行再次校验,就很可能导致用户其实需要支付1w的价格,却因为被篡改了,只要支付1元了。如果一致,才会进行支付达成交易。

3. 如何使用forms组件

3.1 基本格式:

在views.py里面编写以下代码:
from django import forms # 导入forms模板
class MyForms(forms.Form):
# 用户名字符串最小3位,最大8位
username = forms.CharField(min_length=3,max_length=8)
password = forms.CharField(min_length=3,max_length=8)
# email字段必须符合邮箱格式
email = forms.EmailField()

3.2 forms组件校验数据功能

首先,我们需要准备一个测试环境,在pycharm里面已经帮你准备一个测试环境,即pycharm底部的python console,我们在python console里执行以下代码检测forms组件:

from app01 import views
# 1 将带校验的数据组织成字典的形式传入即可
form_obj = views.MyForm({'username':'jason','password':'123','email':'123'}) # 2 判断数据是否合法,注意该方法只有在所有的数据全部合法的情况下才会返回True
form_obj.is_valid()
结果为False # 3 查看所有校验通过的数据
form_obj.cleaned_data
结果为{'username': 'jason', 'password': '123'} # 4 查看所有不符合校验规则以及不符合的原因
form_obj.errors
结果为{
'email': ['Enter a valid email address.']
} # 5 校验数据只校验类中出现的字段 多传不影响 多传的字段直接忽略
form_obj = views.MyForm({'username':'jason','password':'123','email':'123@qq.com','hobby':'study'})
form_obj.is_valid()
结果为True # 6 校验数据 默认情况下 类里面所有的字段都必须传值
form_obj = views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()
结果为False 综上:这也就意味着校验数据的时候 默认情况下数据可以多传但是绝不可能少传

3.3 forms组件生成可用的html标签

forms组件可用帮您渲染获取用户输入的标签(input、select、radio、checkbox等),但是不能渲染提交按钮

第一步:在view.py中创建forms组件的类之后,我们需要定义一个函数,在函数内生成空类对象,再将类对象传递给html页面。

def index(request):
# 1 先产生一个空对象
form_obj = MyForm()
# 2 直接将该空对象传递给html页面
return render(request,'index.html',locals())

第二步:传递到html页面之后,forms组件有三种生成html标签的方式,分别是:

    # 1.第一种渲染方式:代码书写极少,封装程度太高 不便于后续的扩展 一般情况下只在本地测试使用
{{ form_obj.as_p }} #用p标签包裹每个input标签和label标签
{{ form_obj.as_ul }} #用ul标签里的li标签包裹
{{ form_obj.as_table }} #用table的包裹,一行显示
# 2.第二种渲染方式:可扩展性很强 但是需要书写的代码太多 一般情况下不用
<p>{{ form_obj.username.label }}:{{ form_obj.username }}</p> #空对象.字段对象.label属性 获取框的注释 空对象.字段对象 获取框框
<p>{{ form_obj.password.label }}:{{ form_obj.password }}</p>
<p>{{ form_obj.email.label }}:{{ form_obj.email }}</p>
# 3.第三种渲染方式(推荐使用):代码书写简单 并且扩展性也高
{% for form in form_obj %}
<p>{{ form.label }}:{{ form }}</p>
{% endfor %} 补充:label属性默认展示的是类中定义的字段首字母大写的形式
也可以自己修改 直接给字段对象加label属性即可
username = forms.CharField(min_length=3,max_length=8,label='用户名')

3.4 校验之后展示提示信息(格式错误的话进行提示)

渲染完毕之后,当我们在页面输入的信息不符合forms组件命名的字段对象属性要求时,浏览器其实会自动提示您需要输入正确的格式,如下图:

不需要浏览器进行校验提示时,我们只需要在form表单添加一个novalidate属性

<form action="" method="post" novalidate>

因此,我们就需要后端进行一个数据的校验,如何在返回前端页面,展示在页面上:

后端代码部分
def index(request):
# 1 先产生一个空对象
form_obj = MyForm()
if request.method == 'POST':
# 获取用户数据并且校验
"""
1.数据获取繁琐
2.校验数据需要构造成字典的格式传入才行
ps:但是request.POST可以看成就是一个字典
"""
# 3.校验数据
form_obj = MyForm(request.POST)
# 4.判断数据是否合法
if form_obj.is_valid():
# 5.如果合法 操作数据库存储数据
return HttpResponse('OK')
# 5.不合法 有错误
# 2 直接将该form_obj空对象传递给html页面
return render(request,'index.html',locals()) 注意:1.第三步的校验数据对象form_obj必须和产生的空对象名字一样,为什么呢?我们来分析一下后端页面的逻辑:当访问index页面,会先产生一个对象。此时没有post请求,对象会直接传到html页面渲染页面;如果在前端提交数据,产生post请求,我们需要获取前端发来的用户数据进行校验,该数据必须是字典形式,request.POST就是字典格式,直接将其传入myform对象里,并将该对象重新赋值给form_obj,如果不是form_obj则向前端重新渲染的时候就会出错,因为前面是根据form_obj对象来渲染的; 2.forms组件当你的数据不合法的情况下 会保存你上次的数据 让你基于之前的结果进行修改
更加的人性化(其实这就是利用第三步校验,保存页面第一次渲染的样子,如何还附加了一些第一次提交的数据!!理解!!!)
前端代码部分
{% for form in form_obj %}
<p>
{{ form.label }}:{{ form }}
<span style="color: red">{{ form.errors.0 }}</span> #添加一个span标签,显示提示信息
</p>
{% endfor %}

3.5 自定义错误信息提示

class MyForm(forms.Form):
# username字符串类型最小3位最大8位
username = forms.CharField(min_length=3,max_length=8,label='用户名',
error_messages={
'min_length':'用户名最少3位',
'max_length':'用户名最大8位',
'required':"用户名不能为空"
}
)
# password字符串类型最小3位最大8位
password = forms.CharField(min_length=3,max_length=8,label='密码',
error_messages={
'min_length': '密码最少3位',
'max_length': '密码最大8位',
'required': "密码不能为空"
}
)
# email字段必须符合邮箱格式 xxx@xx.com
email = forms.EmailField(label='邮箱',
error_messages={
'invalid':'邮箱格式不正确',
'required': "邮箱不能为空"
}
)

3.6 forms组件的钩子函数

钩子函数是用来在特定的节点自动触发并完成响应操作,它在forms组件里类似校验的第二道关卡,能够让我们自定义校验规则。

在forms组件中有两类钩子:

1.局部钩子

当你需要给单个字段增加校验规则的时候可以使用

2.全局钩子

当你需要给多个字段增加校验规则的时候可以使用

小案例:

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

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

# 钩子函数  在forms组件类里面书写方法即可
# 局部钩子
def clean_username(self): #类里面定义的字段对象会自动创建一个(clear_字段对象名)的函数
# 获取到用户名
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

3.7 为forms组件的字段类型添加样式

针对forms组件渲染的标签,并没有附带任何的样式,我们可以在字段对象里添加一个属性来为不同类型的input框添加样式:

在字段对象中添加以下属性:
widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'})
# PasswordInput这可以改成不同的类型框
# attrs表示为标签添加多个属性
# 多个属性值的话 直接空格隔开即可

3.8 常见的forms组件字段类型

不需要记忆,后期需要用到直接拷贝即可!

1.input框类型
 username = forms.CharField(在括号里指定widget=forms.widgets.PasswordInput改变input框的类型)
2.radio类型
    gender = forms.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
3.select单选下拉框类型
    hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
4.select多选下拉框类型
    hobby1 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
5.单选checkbox
    keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
6.多选checkbox
    hobby2 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)

3.9 forms组件字段对象的常见属性

label		字段名
error_messages 自定义报错信息
initial 默认值
required 控制字段是否必填
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
]
# 正则校验数据 需要先导入一个from django.core.validators import RegexValidator 模块
# 第一参数是校验规则,第二个参数是校验的提示信息
# 可以写多个正则校验规则,从上到下执行校验,需要校验的规则时可以上网搜索

django中的forms组件的更多相关文章

  1. django中的forms组件(权限信息校验,增删改查)

    1.用处 1.用户请求数据验证 2.自动生成错误信息 3.打包用户提交的正确信息 4.如果其中有一个错误了,其他的正确,则保留上次输入的内容 5.自动创建input标签并可以设置样式 6.基于form ...

  2. Django中的form组件

    Django中的form组件有两大作用 1.验证获取正确的结果或者错误信息 2.生成html代码 一.为什么需要form组件呢? 在写form表单,提交数据时,自己写验证的代码是一件非常困难的事情. ...

  3. Django框架的forms组件与一些补充

    目录 一.多对多的三种创建方式 1. 全自动 2. 纯手撸(了解) 3. 半自动(强烈推荐) 二.forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组 ...

  4. [Django高级之forms组件]

    [Django高级之forms组件] forms组件之校验字段 # 第一步:定义一个类,继承forms.Form # 第二步:在类中写字段,要校验的字段,字段属性就是校验规则 # 第三步:实例化得到一 ...

  5. Django基础之forms组件中的ModelForm组件

    Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...

  6. django中的ajax组件

    目录 django中的ajax 向服务器发送请求的途径 Ajax的特点 基于jquery实现的ajax请求 利用ajax实现计算器 利用ajax实现登陆认证 利用form表单进行文件上传 利用ajax ...

  7. Django中的forms一些小点

    1.默认情况下,chrom浏览器会提前对我们的form表单中的数据做校验,如果不想让chrom浏览器给我们做校验,则只需要按照下面的方式处理就可以了 <form method="pos ...

  8. Django中的admin组件分析

    admin的使用介绍 django-admin的使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.可以在项目的 setting ...

  9. django中的分页器组件

    目录 django的组件-分页器 引入分页器 分页器demo 创建数据库模型 url控制器 views视图函数 templates模板 为什么要用分页器 导入分页器 分页器优化1 分页器优化2 有多少 ...

随机推荐

  1. webpack.config.js和vue.config.js的区别

    webpack.config.js是webpack的配置文件,所有使用webpack作为打包工具的项目都可以使用,vue的项目可以使用,react的项目也可以使用. vue.config.js是vue ...

  2. 《回炉重造 Java 基础》——集合(容器)

    整体框架 绿色代表接口/抽象类:蓝色代表类. 主要由两大接口组成,一个是「Collection」接口,另一个是「Map」接口. 前言 以前刚开始学习「集合」的时候,由于没有好好预习,也没有学好基础知识 ...

  3. JS基础二--字面量和变量

       /*       字面量,都是一些不可改变的值,       比如:1 2 3 4 5       字面量都是可以直接使用,但是我们一般不会直接使用字面量.       变量,变量可以用来保存字 ...

  4. Jmeter基础入门应用举例

    举例当然应该有接口下面以常用的百度搜索接口为例: 1.接口地址: http://www.baidu.com/s?ie=utf-8&wd=jmeter性能测试 2.请求参数 ie:编码方式,默认 ...

  5. 聊聊 C++ 和 C# 中的 lambda 玩法

    这几天在看 C++ 的 lambda 表达式,挺有意思,这个标准是在 C11标准 加进去的,也就是 2011 年,相比 C# 2007 还晚了个 4 年, Lambda 这东西非常好用,会上瘾,今天我 ...

  6. CSS 网页字体最佳实践

    一般在网页的字体设置中,可以将字体分类三类: 系统字体:使用系统自带的字体 兜底字体:当系统字体无法正常使用,而兜底的字体 Emoji 字体:显示网页中的表情字体 为了满足不同平台,以及 Emoji ...

  7. BUUCTF-爱因斯坦

    爱因斯坦 16进制打开可以看到存在压缩包,使用binwalk分离出来 提示需要解压密码,按照常理爆破四位数纯数字没有出来,查看图片属性发现密码 得到flag

  8. IDEA中Maven Project所在位置

    难免有小伙伴找不着这个在哪. 一.首先就是可以在下面这个位置查询到: 二.如果找不着,那么在这里找: 三.如果还找不到,那就没有是你刚导入的项目没有Add Maven, 下面这个图是我Add  Mav ...

  9. linux查询文件或者文件夹

    查找目录:find /(查找范围) -name '查找关键字' -type d // 查找fastdfs_storage_data文件夹 find / -name fastdfs_storage_da ...

  10. 高仿Android网易云音乐OkHttp+Retrofit+RxJava+Glide+MVC+MVVM

    简介 这是一个使用Java(以后还会推出Kotlin版本)语言,从0开发一个Android平台,接近企业级的项目(我的云音乐),包含了基础内容,高级内容,项目封装,项目重构等知识:主要是使用系统功能, ...