侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

框架(架构)  /  管理员 发布于 7年前   141

一、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 RegexValidatorclass 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

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


  • 上一条:
    Django 批量插入数据的实现方法
    下一条:
    Django后台管理系统的图文使用教学
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客