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

 更新时间:2020年01月14日 08:27:10   作者:辜老板  
这篇文章主要介绍了Django之form组件自动校验数据实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、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.生成一个对象

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>

第二种方式 {{ 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 }}

第三种方式 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>

六、数据校验

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

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

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

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

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

常用校验参数

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属性
                )

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':'邮箱格式不正确'
  })

手机号类型校验

正则匹配

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

性别校验

  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()  # 单选
  )

爱好多选select 校验1

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

爱好多选chekbox校验2

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

是否记住密码校验

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

七、钩子函数

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

局部钩子

校验用户名中不能包含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

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

相关文章

  • Python爬虫包BeautifulSoup实例(三)

    Python爬虫包BeautifulSoup实例(三)

    这篇文章主要为大家详细介绍了Python爬虫包BeautifulSoup实例,具有一定的参考价值,感兴趣的朋友可以参考一下
    2018-06-06
  • Python根据当前日期取去年同星期日期

    Python根据当前日期取去年同星期日期

    最近做项目,遇到这样的业务开发需求,需要对比当前时间段和去年同星期的时间段的数据,下面小编通过实例代码给大家分享Python根据当前日期取去年同星期日期,需要的朋友参考下
    2019-04-04
  • python实现在图片上画特定大小角度矩形框

    python实现在图片上画特定大小角度矩形框

    这篇文章主要为大家详细介绍了python实现在图片上画特定大小角度矩形框,以及C++的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 基于PyTorch中view的用法说明

    基于PyTorch中view的用法说明

    这篇文章主要介绍了基于PyTorch中view的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • python中upper是做什么用的

    python中upper是做什么用的

    在本篇文章里小编给大家整理的是一篇关于python中upper的作用的相关文章,有需要的朋友们可以参考下。
    2020-07-07
  • 深入浅析python定时杀进程

    深入浅析python定时杀进程

    这篇文章主要介绍了深入浅析python定时杀进程的相关资料,需要的朋友可以参考下
    2016-06-06
  • python 计算数据偏差和峰度的方法

    python 计算数据偏差和峰度的方法

    今天小编就为大家分享一篇python 计算数据偏差和峰度的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • python selenium 弹出框处理的实现

    python selenium 弹出框处理的实现

    这篇文章主要介绍了python selenium 弹出框处理的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-02-02
  • Python字符串替换实例分析

    Python字符串替换实例分析

    这篇文章主要介绍了Python字符串替换的方法,实例对比分析了单个字符替换与字符串替换的相关技巧,非常简单实用,需要的朋友可以参考下
    2015-05-05
  • 详解Python学习之安装pandas

    详解Python学习之安装pandas

    这篇文章主要介绍了Python学习之安装pandas,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04

最新评论