Python中使用django form表单验证的方法


Posted in PHP onJanuary 16, 2017

一. django form表单验证引入  

有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ;

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Form</title>
</head>
<body>
  <div>
    <form action="url" method="post" enctype="multipart/form-data">{% csrf_token %}
      <input type="text" name="username"/>
      <input type="password" name="password"/>
      <input type="submit" value="submit"/>
    </form>
  </div>
</body>

前端提交后台获取:

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def Login(request):
  if request.method == "POST":
    username = request.POST.get("username")
    password = request.POST.get("password")
    return HttpResponse("Hello,%s"%(username))

这样就完成了基本的功能,基本上可以用了。

但是,如果用户输入并未按照要求(比如手机号要输数据11位长度,密码的复杂度等),还有就是提交后再回来已经输入的数据也会没了

当然如果我们手动将输入之后的数据在 views 中都获取到再传递到网页,这样是可行的,但是很不方便,所以 Django 提供了更简单易用的 forms 来解决验证等这一系列的问题

,在这里不得不提Django的插件库真的很强大,简单易扩展,上面的内容只是引进为什么要使用form,下面着重记录django form的使用

二.form表单验证应用

需要在django的APP中新建一个模块form.py,具体内容如下

class RegisterForm(forms.Form):
  email = forms.EmailField(required=True,
               error_messages={'required': "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={'required': "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={'required': "验证码不能为空"})

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>register</title>
</head>
<body>
  <div>
    <form action="url" method="post" enctype="multipart/form-data">
      <input type="text" name="username"/>
      <input type="password" name="password"/>
      <input type="text" name="code"/>
      <input type="submit" value="submit"/>
    </form>
  </div>
</body>

后台views处理

def register(request):
  if request.method == "POST":
    f = Reg_Form(request.POST)
    if f.is_valid():
      user = f.cleaned_data["username"]
      pwd = f.cleaned_data["password"]
      code = f.cleaned_data["code"]
      res_code = request.session.get("code", None)
      result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(user__exact=user).update(status=1)
        request.session["user"] = user
        return redirect("/home")
      else:
        return render(request, "register.html", {"error": f.errors, "form": f})else:return render(request, "register.html")

Reg_Form(request.POST) 使用form类来处理提交的数据来验证数据的合法性,is_valid()合法后的逻辑处理,验证后的数据保存在实例化后返回的cleaned_data中,

cleaned_data是个字典的数据格式,错误信息保存在form.errors中比如说想在views中查看所有报错信息print(f.errors),如果只想看用户的可以

print(form.errors['username'][0])

错误信息我们可以通过 模板渲染回前端页面,例

<form action="/form/" method="POST">
{% csrf_token %}
    <div class="input-group">
      {#接收后台传过来的form对象,自动生成input标签#}
      {{ form.user }}
      {#从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
 {#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
      {% if error.username.0 %}
      <span>{{ error.userusername.0 }}</span>
      {% endif %}
    </div>
    <div class="input-group">
      {{ form.password }}
      {% if error.pwd.0 %}
      <span>{{ error.password .0 }}</span>
      {% endif %}
    </div>
    <div>
      <input type="submit" value="提交" />
    </div>
  </form>

三.自生成input框

Form类

class RegisterForm(forms.Form):
  style = 'form-control input-lg'
  phone = forms.CharField(widget=forms.TextInput(attrs={'class': style,
                              'name': 'title'})),
              required=True,
              error_messages={'required': ugettext_lazy('*Required')})
  code = forms.CharField(widget=forms.NumberInput(attrs={'placeholder': '验证码',
                              'class': style}),
              min_length=4,
              max_length=4,
              required=True,
              error_messages={'required': ugettext_lazy('*Required')})
  password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '请输入密码',
                                 'class': style}),
                min_length=6,
                required=True,
                error_messages={'required': ugettext_lazy('*Required')})

views

def register(request):
  if request.method == "POST":
    f = RegisterForm(request.POST)
    if f.is_valid():
      user = f.cleaned_data["username"]
      pwd = f.cleaned_data["password"]
      code = f.cleaned_data["code"]
      res_code = request.session.get("CheckCode", None)
      result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(user__exact=user).update(status=1)
        request.session["user"] = user
        return redirect("/home")
      else:
        return render(request, "login.html", {"error": f.errors, "form": f})
    else:
      return render(request, "login.html", {"error": f.errors, "form": f})
  else:
# 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空
    f = Log_Form()
    return render(request, "login.html", {"form": f})

前端页面

<body>
  <form action="/form/" method="POST">
{% csrf_token %}
    <div class="input-group">
{#      接收后台传过来的form对象,自动生成input标签#}
      {{ form.user }}
{#      从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
{#      如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
    <div class="input-group">
      {{ form.email }}
      {% if error.email.0 %}
      <span>{{ error.email.0 }}</span>
      {% endif %}
    </div>
     <div class="input-group">
      {{ form.password }}
      {% if error.password.0 %}
      <span>{{ error.password.0 }}</span>
      {% endif %}
    </div>
       <div class="input-group">
      {{ form.code }}
      {% if error.book_type.0 %}
      <span>{{ error.code.0 }}</span>
      {% endif %}
    </div>
    <div>
      <input type="submit" value="提交" />
    </div>
  </form>
</body>
</html>

四.Form验证完善

https://docs.djangoproject.com/en/dev/ref/forms/validation/

form验证的运行顺序是init,clean,validte,save

其中clean和validate会在form.is_valid()方法中被先后调用

clean等步骤遇到的异常:Exception Value: argument of type 'NoneType' is not iterable.

可能是cleaned_data中某个字段值应该是个列表,实际上却是空值。

clean方法重写时一定不要忘了return cleaned_data

这样重写可以使用户提交的数据在form类中执行检测完后返回数据给用户,数据合法后进行逻辑处理,不需要再进行处理返回用户,更方便更合理

补充:

5.form的四种初始化方式

①实例化oneform(initial={'onefield':value})

②定义字段时给初始化值oneformfield = forms.CharField(initial=value)

③重写Form类的__init__()方法:self.fields['onefield'].initial = value

④当给form传参instanse(即oneform(instanse=onemodel_instance))时,前三种初始化方法会全部失效,即使重写__init__时,先调用父类的__init__再使用方法③,仍然无效(不是很爽)。

这时想重新初始化字段值只能在__init__()里 self.initial['title'] = value,直接对Form类的initial属性字典赋值。

from django import forms
class RegisterForm(forms.Form):
  email = forms.EmailField(required=True,
               error_messages={'required': "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={'required': "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={'required': "验证码不能为空"})
  def clean(self):
    # 用户名
    try:
      email = self.cleaned_data['email']
    except Exception as e:
      raise forms.ValidationError(u"注册账号需为邮箱格式")
    # 验证邮箱
    user = User.objects.filter(username=email)
    if user: # 邮箱已经被注册了
      raise forms.ValidationError(u"邮箱已被注册")
    # 密码
    try:
      password = self.cleaned_data['password']
    except Exception as e:
      print('except: ' + str(e))
      raise forms.ValidationError(u"请输入至少6位密码")
    return self.cleaned_data

以上所述是小编给大家介绍的Python中使用django form表单验证的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
php框架Phpbean说明
Jan 10 PHP
对text数据类型不支持代码页转换 从: 1252 到: 936
Apr 23 PHP
PHP中使用unset销毁变量并内存释放问题
Jul 05 PHP
基于Zend的Captcha机制的应用
May 02 PHP
解析PHP对现有搜索引擎的调用
Jun 25 PHP
php加密解密函数authcode的用法详细解析
Oct 28 PHP
PHP中判断变量为空的几种方法小结
Nov 12 PHP
codeigniter实现get分页的方法
Jul 10 PHP
深入浅析PHP无限极分类的案例教程
May 09 PHP
PHP用FTP类上传文件视频等的简单实现方法
Sep 23 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
May 08 PHP
php输出形式实例整理
May 05 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
Jan 16 #PHP
php实现文件上传及头像预览功能
Jan 15 #PHP
给大家分享几个常用的PHP函数
Jan 15 #PHP
详解Yii实现分页的两种方法
Jan 14 #PHP
PHP微信分享开发详解
Jan 14 #PHP
常用PHP封装分页工具类
Jan 14 #PHP
详解php用curl调用接口方法,get和post两种方式
Jan 13 #PHP
You might like
星际争霸中的热键
2020/03/04 星际争霸
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
2008/10/13 PHP
php实现excel中rank函数功能的方法
2015/01/20 PHP
Laravel5.5新特性之友好报错以及展示详解
2017/08/13 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
asp.net下利用js实现返回上一页的实现方法小集
2009/11/24 Javascript
jQueryPad 实用的jQuery测试工具(支持IE,chrome,FF)
2010/05/22 Javascript
jQuery总体架构的理解分析
2011/03/07 Javascript
JavaScript学习笔记(一) js基本语法
2011/10/25 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
对Web开发中前端框架与前端类库的一些思考
2015/03/27 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
JQuery实现文字无缝滚动效果示例代码(Marquee插件)
2017/03/07 Javascript
React入门教程之Hello World以及环境搭建详解
2017/07/11 Javascript
详解Vue实战指南之依赖注入(provide/inject)
2018/11/13 Javascript
20多个小事例带你重温ES10新特性(小结)
2019/09/29 Javascript
Vue组件简易模拟实现购物车
2020/12/21 Vue.js
详解Python中__str__和__repr__方法的区别
2015/04/17 Python
基于进程内通讯的python聊天室实现方法
2015/06/28 Python
python读取文件名并改名字的实例
2019/01/07 Python
Python的Lambda函数用法详解
2019/09/03 Python
python 使用递归回溯完美解决八皇后的问题
2020/02/26 Python
Python学习之路安装pycharm的教程详解
2020/06/17 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
美特斯邦威官方商城:邦购网
2016/10/13 全球购物
英国剑桥包中文官网:The Cambridge Satchel Company中国
2018/11/06 全球购物
彪马土耳其官网:PUMA土耳其
2019/07/14 全球购物
法国滑雪假期的专家:Ski Planet
2019/11/02 全球购物
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
研究生自荐信
2013/10/09 职场文书
师范生实习自我鉴定
2013/11/01 职场文书
幼儿园小班个人总结
2015/02/12 职场文书
八年级作文之友谊
2019/12/02 职场文书
vue实现input输入模糊查询的三种方式
2022/08/14 Vue.js