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 和 MySQL 开发的 8 个技巧
Oct 09 PHP
加速XP搜索功能堪比vista
Mar 22 PHP
在PHP中检查PHP文件是否有语法错误的方法
Dec 23 PHP
整理的一些实用WordPress后台MySQL操作命令
Jan 07 PHP
解决FastCGI 进程超过了配置的活动超时时限的问题
Jul 03 PHP
Smarty局部缓存的几种方法简介
Jun 17 PHP
完美实现wordpress禁止文章修订和自动保存的方法
Nov 03 PHP
详谈PHP程序Laravel 5框架的优化技巧
Jul 18 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
Oct 22 PHP
Laravel修改验证提示信息为中文的示例
Oct 23 PHP
PHP扩展类型及安装方式解析
Apr 27 PHP
imagettftext() 失效,不起作用
Mar 09 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
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
php 网上商城促销设计实例代码
2012/02/17 PHP
PHP入门教程之正则表达式基本用法实例详解(正则匹配,搜索,分割等)
2016/09/11 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
jQuery select的操作实现代码
2009/05/06 Javascript
jQuery入门第一课 jQuery选择符
2010/03/14 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
jQuery检测输入的字符串包含的中英文的数量
2015/04/17 Javascript
简介JavaScript中的getSeconds()方法的使用
2015/06/10 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
js css自定义分页效果
2017/02/24 Javascript
jQuery实现弹窗居中效果类似alert()
2017/02/27 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
JS获取月的第几周和年的第几周实例代码
2018/12/05 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
JavaScript实现单点登录的示例
2020/09/23 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
Mac 上切换Python多版本
2017/06/17 Python
Python编程实现正则删除命令功能
2017/08/30 Python
解决python给列表里添加字典时被最后一个覆盖的问题
2019/01/21 Python
Python多项式回归的实现方法
2019/03/11 Python
关于python的缩进规则的知识点详解
2020/06/22 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
土耳其时尚潮流在线购物网站:Trendyol
2017/10/10 全球购物
机电一体化专业推荐信
2013/12/03 职场文书
学校招生宣传广告词
2014/03/19 职场文书
歌颂祖国演讲稿
2014/05/04 职场文书
2014领导干部学习焦裕禄同志先进事迹思想汇报
2014/09/19 职场文书
2014年大学团支部工作总结
2014/12/02 职场文书
公司奖励通知
2015/04/21 职场文书
元旦晚会开场白
2015/05/29 职场文书
redis数据结构之压缩列表
2022/03/21 Redis
Python docx库删除复制paragraph及行高设置图片插入示例
2022/07/23 Python