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

 更新时间:2017年01月16日 10:49:55   作者:jl_bai  
这篇文章主要介绍了Python中使用django form表单验证的方法,需要的朋友可以参考下

一. 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表单验证的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • ThinkPHP之用户注册登录留言完整实例

    ThinkPHP之用户注册登录留言完整实例

    这篇文章主要介绍了ThinkPHP之用户注册登录留言完整实例,有助于详细了解ThinkPHP的运作流程,需要的朋友可以参考下
    2014-07-07
  • PHP文件读取功能的应用实例

    PHP文件读取功能的应用实例

    这篇文章主要介绍了PHP文件读取功能的应用实例以及常用的文件数据读取的函数的使用方法及区别,非常的详细,有需要的小伙伴可以参考下。
    2015-05-05
  • PHP实现链式操作的原理详解

    PHP实现链式操作的原理详解

    下面小编就为大家带来一篇PHP实现链式操作的原理详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • PHP实现多条件查询实例代码

    PHP实现多条件查询实例代码

    在我们的网站设计过程中,经常会用到多条件查询,本文的源码是一个二手房屋查询的例子。在本例中,我们要实现能够通过地理位置,物业类型,房屋价格,房屋面积及信息发布日期等多个条件查询到客户所需的资料。
    2010-07-07
  • PHP中可以自动分割查询字符的Parse_str函数使用示例

    PHP中可以自动分割查询字符的Parse_str函数使用示例

    这篇文章主要介绍了PHP中可以自动分割查询字符的Parse_str函数使用示例,小编也没见过的一个函数,这下分割URL中的查询字符串就方便了,需要的朋友可以参考下
    2014-07-07
  • YII视图整合kindeditor扩展的方法

    YII视图整合kindeditor扩展的方法

    这篇文章主要介绍了YII视图整合kindeditor扩展的方法,较为详细的分析了Yii框架整合kindeditor的功能实现代码与设置相关技巧,需要的朋友可以参考下
    2016-07-07
  • Yii2框架引用bootstrap中日期插件yii2-date-picker的方法

    Yii2框架引用bootstrap中日期插件yii2-date-picker的方法

    这篇文章主要介绍了Yii2框架引用bootstrap中日期插件yii2-date-picker的方法,实例分析了yii2-date-picker插件的具体使用步骤与相关技巧,需要的朋友可以参考下
    2016-01-01
  • ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解

    ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解

    这篇文章主要介绍了ThinkPHP框架整合微信支付之Native 扫码支付模式,结合图文形式详细分析了thinkPHP整合微信扫码支付功能的具体步骤与相关操作技巧,以及与模式一的区别,需要的朋友可以参考下
    2019-04-04
  • PHP 实现字符串翻转(包含中文汉字)的实现代码

    PHP 实现字符串翻转(包含中文汉字)的实现代码

    本篇文章主要介绍了PHP 实现字符串翻转(包含中文汉字)的实现代码,在PHP面试题中经常遇到,有兴趣的可以了解一下。
    2017-04-04
  • php二维数组按某个键值排序的实例讲解

    php二维数组按某个键值排序的实例讲解

    今天小编就为大家分享一篇关于php二维数组按某个键值排序的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02

最新评论