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在DOS命令行下却无法链接MySQL的技术笔记
Dec 29 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
Jun 14 PHP
php多个字符串替换成同一个的解决方法
Jun 18 PHP
php while循环得到循环次数
Oct 26 PHP
php实现的支持断点续传的文件下载类
Sep 23 PHP
php中Array2xml类实现数组转化成XML实例
Dec 08 PHP
Win7下手动安装apache2.2、php5.4笔记
Apr 03 PHP
phpMyAdmin安装并配置允许空密码登录
Jul 04 PHP
php微信公众平台示例代码分析(二)
Dec 06 PHP
详解php框架Yaf路由重写
Jun 20 PHP
Laravel中前端js上传图片到七牛云的示例代码
Sep 04 PHP
laravel 修改记住我功能的cookie保存时间的方法
Oct 14 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
PHP函数preg_match_all正则表达式的基本使用详细解析
2013/08/31 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
将jQuery应用于login页面的问题及解决
2009/10/17 Javascript
js jquery数组介绍
2012/07/15 Javascript
js 动态修改css文件的方法
2014/08/05 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
高性能JavaScript 重排与重绘(2)
2015/08/11 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
超全面的JavaScript开发规范(推荐)
2017/01/21 Javascript
Angular2库初探
2017/03/01 Javascript
微信小程序新增的拖动组件movable-view使用教程
2017/05/20 Javascript
浅析vue-router原理
2018/10/19 Javascript
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
在Django框架中设置语言偏好的教程
2015/07/27 Python
浅谈python迭代器
2017/11/08 Python
python 编码规范整理
2018/05/05 Python
python实现彩色图转换成灰度图
2019/01/15 Python
Python3实现的判断环形链表算法示例
2019/03/07 Python
python简单验证码识别的实现方法
2019/05/10 Python
基于python计算滚动方差(标准差)talib和pd.rolling函数差异详解
2020/06/08 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
python 制作网站小说下载器
2021/02/20 Python
利用html5 canvas动态画饼状图的示例代码
2018/04/02 HTML / CSS
AmazeUI折叠式卡片布局,整合内容列表、表格组件实现
2020/08/20 HTML / CSS
Melissa鞋马来西亚官方网站:MDreams马来西亚
2018/04/05 全球购物
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
英文版餐饮运营管理求职信
2013/11/06 职场文书
个人廉洁自律承诺书
2014/03/27 职场文书
警示教育活动总结
2014/05/05 职场文书
物业品质提升方案
2014/06/08 职场文书
班级标语大全
2014/06/21 职场文书
鲁迅故居导游词
2015/02/05 职场文书
数学教师个人工作总结
2015/02/06 职场文书
Spring Boot DevTools 全局配置学习指南
2022/03/31 Java/Android
redis protocol通信协议及使用详解
2022/07/15 Redis