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 执行字符串表达式函数(eval exec execfile)
Aug 11 Python
python同时给两个收件人发送邮件的方法
Apr 30 Python
Python实现模拟分割大文件及多线程处理的方法
Oct 10 Python
python Opencv将图片转为字符画
Feb 19 Python
python中的常量和变量代码详解
Jul 25 Python
python 调用有道api接口的方法
Jan 03 Python
Python中一个for循环循环多个变量的示例
Jul 16 Python
python3.6+django2.0+mysql搭建网站过程详解
Jul 24 Python
详谈tensorflow gfile文件的用法
Feb 05 Python
windows下python安装pip方法详解
Feb 10 Python
Python图像识别+KNN求解数独的实现
Nov 13 Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 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制作静态网站的模板框架(二)
2006/10/09 PHP
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
PHP中余数、取余的妙用
2015/06/29 PHP
PHP读取zip文件的方法示例
2016/11/17 PHP
jQuery对象和DOM对象相互转化
2009/04/24 Javascript
犀利的js 函数集合
2009/06/11 Javascript
javascript 函数及作用域总结介绍
2013/11/12 Javascript
深入理解Javascript中this的作用域
2014/08/12 Javascript
jQuery Ajax()方法使用指南
2014/11/19 Javascript
jQuery提示插件alertify使用指南
2015/04/21 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
EditPlus 正则表达式 实战(3)
2016/12/15 Javascript
微信小程序之蓝牙的链接
2017/09/26 Javascript
如何使用puppet替换文件中的string
2018/12/06 Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
2019/02/20 Javascript
通过js实现压缩图片上传功能
2020/02/25 Javascript
js实现鼠标点击飘爱心效果
2020/08/19 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
JS数组索引检测中的数据类型问题详解
2021/01/11 Javascript
[59:32]Liquid vs Fnatic 2019国际邀请赛淘汰赛败者组BO1 8.20.mp4
2020/07/19 DOTA
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
利用numpy实现一、二维数组的拼接简单代码示例
2017/12/15 Python
TensorFlow实现模型评估
2018/09/07 Python
Python实现二叉树的最小深度的两种方法
2019/09/30 Python
Anaconda配置pytorch-gpu虚拟环境的图文教程
2020/04/16 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
python网络爬虫实现发送短信验证码的方法
2021/02/25 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述
2013/01/31 HTML / CSS
世界上最大的餐具公司:Oneida
2016/12/17 全球购物
什么是Deployment descriptors;都有什么类型的部署描述符
2015/07/28 面试题
Java中的异常处理机制的简单原理和应用
2013/04/27 面试题
优秀大学生求职自荐信范文
2014/04/19 职场文书
幼儿园个人总结
2015/02/28 职场文书
飞越疯人院观后感
2015/06/09 职场文书
MySQL 数据库范式化设计理论
2022/04/22 MySQL