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. poj1475 -- Pushing Boxes

    这道题其实挺有趣 的,这让我想起小时候诺基亚手机上的推箱子游戏(虽然一点也不好玩) (英文不好-->)  题意翻译: 初始人(S),箱子(B),目的地(T)用人把箱子推到 T最小步数及其路径(满 ...

  2. 「ARC138E」Decreasing Subsequence(n logn 做法)

    考虑一张 \(n\) 个点的图(\(V=\{0,1,\cdots,n\}\)):点 \(i\) 连向 \(a_i-1\),即 \(\text{index}\) 连向 \(\text{value}\). ...

  3. 管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程

    前言 在平常的后端项目开发中,状态机模式的使用其实没有大家想象中那么常见,笔者之前由于不在电商领域工作,很少在业务代码中用状态机来管理各种状态,一般都是手动get/set状态值.去年笔者进入了电商领域 ...

  4. fiddler的安装以及使用同时对Android 与IOS 抓包配置进行分析 进阶 一

    由于工作方向的原因,很久没有用过APP抓包工具了,有那么一天遇到了bug需要协助开发工程师进行定位分析,然后又重新梳理了一下之前常用的抓包工具,这里重点介绍一下目前市面上最流行的几款抓包工具,根据自己 ...

  5. 数字化转型之数字资产知识库(springboot+es+vue+neo4j)

    前言 在数字化高度普及的时代,企事业机关单位在日常工作中会产生大量的文档,例如医院制度汇编,企业知识共享库等.针对这些文档性的东西,手工纸质化去管理是非常消耗工作量的,并且纸质化查阅难,易损耗,所以电 ...

  6. 关于Node.js 链接mysql超时处理(默认8小时)

    备注:这是在pm2配置node环境下,超过8小时mysql自动关闭的情况下出现的解决方法:1.封装mysql.js var mysql = require('mysql'); var connecti ...

  7. python 基础知识-day10(面向对象)

    1.面向对象的概念 拥有共同属性的一类进行归类的过程叫做面向对象. 2.注意事项 class定义类的时候,类名的首字母必须大写 3.面向对象案例 1 class Person(object): 2 d ...

  8. Maven的安装 和idea的配置

    Maven的安装 和idea的配置 工欲善其事 必先利其器 1 下载maven 官网 下滑 找到Files tar.gz 是linux系统的 .zip window系统 2 maven安装和配置到环境 ...

  9. UiPath存在元素Element Exists的介绍和使用

    一.Element Exists的介绍 使您能够验证UI元素是否存在,即使它不可见,输出的是一个布尔值 二.Element Exists在UiPath中的使用 1. 打开设计器,在设计库中新建一个Se ...

  10. jieba分词原理解析:用户词典如何优先于系统词典

    目标 查看jieba分词组件源码,分析源码各个模块的功能,找到分词模块,实现能自定义分词字典,且优先级大于系统自带的字典等级,以医疗词语邻域词语为例. jieba分词地址:github地址:https ...