Django之form组件自动校验数据实现


Posted in Python onJanuary 14, 2020

一、form介绍

我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。

与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。

Django form组件就实现了上面所述的功能。

总结一下,其实form组件的主要功能如下:

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

二、普通方式手写注册功能

views.py

# 注册
def register(request):
  error_msg = ""
  if request.method == "POST":
    username = request.POST.get("name")
    pwd = request.POST.get("pwd")
    # 对注册信息做校验
    if len(username) < 6:
      # 用户长度小于6位
      error_msg = "用户名长度不能小于6位"
    else:
      # 将用户名和密码存到数据库
      return HttpResponse("注册成功")
  return render(request, "register.html", {"error_msg": error_msg})

register.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>注册页面</title>
</head>
<body>
<form action="/reg/" method="post">
  {% csrf_token %}
  <p>
    用户名:
    <input type="text" name="name">
  </p>
  <p>
    密码:
    <input type="password" name="pwd">
  </p>
  <p>
    <input type="submit" value="注册">
    <p style="color: red">{{ error_msg }}</p>
  </p>
</form>
</body>
</html>

三、使用form组件实现注册功能

views.py

先定义好一个RegForm类:

from django import forms

# 按照Django form组件的要求自己写一个类
class RegForm(forms.Form):
  name = forms.CharField(label="用户名")
  pwd = forms.CharField(label="密码")

再写一个视图函数:

# 使用form组件实现注册方式
def register2(request):
  form_obj = RegForm()
  if request.method == "POST":
    # 实例化form对象的时候,把post提交过来的数据直接传进去
    form_obj = RegForm(request.POST)
    # 调用form_obj校验数据的方法
    if form_obj.is_valid():
      return HttpResponse("注册成功")
  return render(request, "register2.html", {"form_obj": form_obj})

register2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>注册2</title>
</head>
<body>
  <form action="/reg2/" method="post" novalidate autocomplete="off">
    {% csrf_token %}
    <div>
      <label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
      {{ form_obj.name }} {{ form_obj.name.errors.0 }}
    </div>
    <div>
      <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
      {{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
    </div>
    <div>
      <input type="submit" class="btn btn-success" value="注册">
    </div>
  </form>
</body>
</html>

看网页效果发现 也验证了form的功能:

  • 前端页面是form类的对象生成的 -->生成HTML标签功能
  • 当用户名和密码输入为空或输错之后 页面都会提示 -->用户提交校验功能
  • 当用户输错之后 再次输入 上次的内容还保留在input框 -->保留上次输入内容

四、pycharm的专属测试环境

1.使用方法

1.导入要测试的py文件

2.生成一个对象

Django之form组件自动校验数据实现

Django之form组件自动校验数据实现

2.本地校验测试的一些参数

from_obj.is_valid()     //判断校验是否通过
from_obj.cleaned_data    //拿到当前符号校验的数据{'username': '111', 'password': '111'}
form_obj.errors       //拿到当前校验不通过的数据

少传参数Flalse,多传Trun。因为少传了拿不到校验的数据,多传了也不会使用。这是字典的形式

五、html自动生成input用户输入框的三种方式

forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签 不渲染按钮和form表单标签

渲染出来的每一个input提示信息都是类中字段首字母大写

class MyRegForm(forms.Form):
  username = forms.CharField(max_length=8, min_length=3) # 最长8位,最短3位
  password = forms.CharField(max_length=8, min_length=3) # 最长8位,最短3位
  email = forms.EmailField() # 邮箱验证
  
def reg(request):
  # 1 先生成一个空的类对象
  form_obj = MyRegForm()
  if request.method == 'POST':
    # 3 获取用户数据并交给forms组件校验 request.POST
    form_obj = MyRegForm(request.POST)
    # 4 获取校验结果
    if form_obj.is_valid():
      return HttpResponse('数据没问题')
    else:
      # 5 获取校验失败的字段和提示信息
      print(form_obj.errors)
  # 2 直接将该对象传给前端页面
  return render(request, 'reg.html', locals())

第一种方式 {{ form_obj.as_p }} (不推荐)

不推荐,封装程度高,扩展性低。一般测试本地用

<body>
<p>第一种渲染方式:多个p标签 本地测试方便 封装程度太高了 不便于扩展</p>
{{ form_obj.as_p }}
{#{{ form_obj.as_ul }}#}
{#{{ form_obj.as_table }}#}
</body>

Django之form组件自动校验数据实现

第二种方式 {{ form_obj.username }} (不推荐)

不推荐,扩展性较高 ,书写较为繁琐,每一个input框都需要自己手动写

<p>第二种渲染方式: 扩展性较高 书写较为繁琐</p>
<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
{{ form_obj.username }}
{{ form_obj.password.label }}{{ form_obj.password }}
{{ form_obj.email.label }}{{ form_obj.email }}

Django之form组件自动校验数据实现

第三种方式 for循环 (推荐)

推荐使用,for循环方式

{{ form.errors.0 }} # 这个是模板语法

<p>第三种渲染方式 推荐使用</p>
<form action="" method="post" novalidate>
  {% for form in form_obj %}
  <p>
    {{ form.label }}{{ form }}
    <span>{{ form.errors.0 }}</span>
  </p>
  {% endfor %}
  <input type="submit">
</form>

Django之form组件自动校验数据实现

Django之form组件自动校验数据实现

六、数据校验

*******数据校验一个前后端都得有 但是前端的校验弱不禁风 可有可无

而后端的校验则必须非常全面

如何取消浏览器自动帮我们校验的功能?

在form后加参数 no validate,不验证

form表单取消前端浏览器自动校验功能 
  <form action="" method="post" novalidate>

Django之form组件自动校验数据实现

常用校验参数

max_length //允许输入的最大长度
min_length //最小长度
label input的提示信息,name、password等
error_messages 自定义报错的提示信息
'max_length':"用户名最长8位",
'min_length':"用户名最短3位",
'required':"用户名不能为空"
required 设置字段是否允许为空
initial 设置默认值
widget 控制type类型及属性

使用方式

CharField用户名类型校验

from django.forms import widgets  //不导入也可以,没提示

class MyRegForm(forms.Form):
  # 用户名最少3位最多8位
  username = forms.CharField(max_length=8,min_length=3,label='用户名',
                error_messages={   //报错信息的提示
                  'max_length':"用户名最长8位",
                  'min_length':"用户名最短3位",
                  'required':"用户名不能为空"
                },required=False,initial='jeff', // 为空和默认值
                widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2'}),    //设置input的type属性为text,及class属性
                )

Django之form组件自动校验数据实现

password校验

class LoginForm(forms.Form):
  ...
  pwd = forms.CharField(
    min_length=6,
    label="密码",
    widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
  )

邮箱类型校验

class MyRegForm(forms.Form):
  # email字段必须填写符合邮箱格式的数据
  email = forms.EmailField(label='邮箱',error_messages={
    'required':'邮箱必填',
    'invalid':'邮箱格式不正确'
  })

Django之form组件自动校验数据实现

手机号类型校验

正则匹配

from django.core.validators import RegexValidator
class MyRegForm(forms.Form):
  # 手机号
  phone = forms.CharField(
    validators=[
      RegexValidator(r'^[0-9]+$', '请输入数字'),  
      RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
    ]
  )

Django之form组件自动校验数据实现

性别校验

gender = forms.ChoiceField(
    choices=((1, "男"), (2, "女"), (3, "保密")),
    label="性别",
    initial=3,
    widget=forms.widgets.RadioSelect()
  )

爱好单选 select校验

hobby = forms.ChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=3,
    widget=forms.widgets.Select()  # 单选
  )

Django之form组件自动校验数据实现

爱好多选select 校验1

hobby1 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.SelectMultiple()
  )

Django之form组件自动校验数据实现

爱好多选chekbox校验2

hobby2 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.CheckboxSelectMultiple()
  )

Django之form组件自动校验数据实现

是否记住密码校验

keep = forms.ChoiceField(
    label="是否记住密码",
    initial="checked",
    widget=forms.widgets.CheckboxInput()
  )

Django之form组件自动校验数据实现

七、钩子函数

# 如果你想同时操作多个字段的数据你就用全局钩子
# 如果你想操作单个字段的数据 你就用局部钩子
钩子勾回来处理完之后,还要还回去的

局部钩子

校验用户名中不能包含666

# 局部钩子
# 这里的self是自己类,MyRegForm
  def clean_username(self):
    username = self.cleaned_data.get('username')
    if '666' in username:
      self.add_error('username','光喊666是不行的')
    return username

全局钩子

两次密码验证

class MyRegForm(forms.Form):
  # 密码
  password = forms.CharField(max_length=8,min_length=3,label='密码',
                widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
               )
  # 密码验证
  re_password = forms.CharField(max_length=8,min_length=3,label='确认密码',
                widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                 )

  def clean(self):
    # 这里的self是自己类,MyRegForm
    # 校验密码和确认密码是否一致
    password = self.cleaned_data.get('password')
    re_password = self.cleaned_data.get('confirm_password')
    if not password == re_password:
      # 展示提示信息
      self.add_error('re_password','两次密码不一致')
      return self.cleaned_data

Django之form组件自动校验数据实现

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Tkinter简单布局实例教程
Sep 03 Python
Python3.6正式版新特性预览
Dec 15 Python
浅谈python中字典append 到list 后值的改变问题
May 04 Python
Python返回数组/List长度的实例
Jun 23 Python
Python SQL查询并生成json文件操作示例
Aug 17 Python
Python 带有参数的装饰器实例代码详解
Dec 06 Python
Apache部署Django项目图文详解
Jul 30 Python
Django+Celery实现动态配置定时任务的方法示例
May 26 Python
Python logging日志模块 配置文件方式
Jul 12 Python
python调用百度AI接口实现人流量统计
Feb 03 Python
python爬不同图片分别保存在不同文件夹中的实现
Apr 02 Python
python实现简单倒计时功能
Apr 21 Python
简单了解python filter、map、reduce的区别
Jan 14 #Python
Python vtk读取并显示dicom文件示例
Jan 13 #Python
Python解析多帧dicom数据详解
Jan 13 #Python
python 将dicom图片转换成jpg图片的实例
Jan 13 #Python
基于Python和PyYAML读取yaml配置文件数据
Jan 13 #Python
Python 实现判断图片格式并转换,将转换的图像存到生成的文件夹中
Jan 13 #Python
利用python实现.dcm格式图像转为.jpg格式
Jan 13 #Python
You might like
php实现文件下载功能的几个代码分享
2014/05/10 PHP
PHP生成条形图的方法
2014/12/10 PHP
基于php编程规范(详解)
2017/08/17 PHP
PHP实现简单的模板引擎功能示例
2017/09/02 PHP
JavaScript delete操作符应用实例
2009/01/13 Javascript
Javascript变量函数浅析
2011/09/02 Javascript
人人网javascript面试题 可以提前实现下
2012/01/05 Javascript
js移除事件 js绑定事件实例应用
2012/11/28 Javascript
js中onload与onunload的使用示例
2013/08/25 Javascript
angularJS 入门基础
2015/02/09 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
理解javascript正则表达式
2016/03/08 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
深入解析JavaScript中的立即执行函数
2016/05/21 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
详解wow.js中各种特效对应的类名
2017/09/13 Javascript
Vue项目中使用Vux的安装过程
2018/05/01 Javascript
如何为你的JavaScript代码日志着色详解
2019/04/08 Javascript
vue项目或网页上实现文字转换成语音播放功能
2020/06/09 Javascript
Openlayers实现距离面积测量
2020/09/28 Javascript
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
python 专题九 Mysql数据库编程基础知识
2017/03/16 Python
Django框架orM与自定义SQL语句混合事务控制操作
2019/06/27 Python
python with语句的原理与用法详解
2020/03/30 Python
Python实现AI换脸功能
2020/04/10 Python
python 制作python包,封装成可用模块教程
2020/07/13 Python
CSS3伪类选择器:nth-child()
2009/04/02 HTML / CSS
HTML5打开本地app应用的方法
2016/03/31 HTML / CSS
Nike爱尔兰官方网站:Nike.com (IE)
2018/03/12 全球购物
捷克移动配件网上商店:ProMobily.cz
2019/03/15 全球购物
八年级英语教学反思
2014/01/09 职场文书
2014年司法局工作总结
2014/12/11 职场文书
学生自我评语
2015/01/04 职场文书
小学语文教学反思范文
2016/03/03 职场文书