首页 后端开发 Python教程 Python中使用django form表单验证的方法

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

Mar 30, 2017 pm 05:20 PM

一. django form表单验证引入  

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

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Form</title>
</head>
<body>
  <p>
    <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>
  </p>
</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={&#39;required&#39;: "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={&#39;required&#39;: "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={&#39;required&#39;: "验证码不能为空"})
登录后复制

前端页面

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>register</title>
</head>
<body>
  <p>
    <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>
  </p>
</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(userexact=user,pwdexact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(userexact=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[&#39;username&#39;][0])
登录后复制

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

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

三.自生成input框

Form类

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

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(userexact=user,pwdexact=pwd)
      if code.upper() == res_code.upper() and result:
        models.UserInfo.objects.filter(userexact=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 %}
    <p class="input-group">
{#      接收后台传过来的form对象,自动生成input标签#}
      {{ form.user }}
{#      从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
{#      如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
    <p class="input-group">
      {{ form.email }}
      {% if error.email.0 %}
      <span>{{ error.email.0 }}</span>
      {% endif %}
    </p>
     <p class="input-group">
      {{ form.password }}
      {% if error.password.0 %}
      <span>{{ error.password.0 }}</span>
      {% endif %}
    </p>
       <p class="input-group">
      {{ form.code }}
      {% if error.book_type.0 %}
      <span>{{ error.code.0 }}</span>
      {% endif %}
    </p>
    <p>
      <input type="submit" value="提交" />
    </p>
  </form>
</body>
</html>
登录后复制

四.Form验证完善

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={&#39;required&#39;: "邮箱不能为空"})
  password = forms.CharField(max_length=120,
                min_length=6,
                required=True,
                error_messages={&#39;required&#39;: "密码不能为空"})
  invite_code = forms.CharField(required=True,error_messages={&#39;required&#39;: "验证码不能为空"})
  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中文网的支持!

更多Python中使用django form表单验证的方法相关文章请关注PHP中文网!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何解决Linux终端中查看Python版本时遇到的权限问题? 如何解决Linux终端中查看Python版本时遇到的权限问题? Apr 01, 2025 pm 05:09 PM

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

如何在10小时内通过项目和问题驱动的方式教计算机小白编程基础? 如何在10小时内通过项目和问题驱动的方式教计算机小白编程基础? Apr 02, 2025 am 07:18 AM

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...

在Python中如何高效地将一个DataFrame的整列复制到另一个结构不同的DataFrame中? 在Python中如何高效地将一个DataFrame的整列复制到另一个结构不同的DataFrame中? Apr 01, 2025 pm 11:15 PM

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

如何在使用 Fiddler Everywhere 进行中间人读取时避免被浏览器检测到? 如何在使用 Fiddler Everywhere 进行中间人读取时避免被浏览器检测到? Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere进行中间人读取时如何避免被检测到当你使用FiddlerEverywhere...

Uvicorn是如何在没有serve_forever()的情况下持续监听HTTP请求的? Uvicorn是如何在没有serve_forever()的情况下持续监听HTTP请求的? Apr 01, 2025 pm 10:51 PM

Uvicorn是如何持续监听HTTP请求的?Uvicorn是一个基于ASGI的轻量级Web服务器,其核心功能之一便是监听HTTP请求并进�...

Python中如何通过字符串动态创建对象并调用其方法? Python中如何通过字符串动态创建对象并调用其方法? Apr 01, 2025 pm 11:18 PM

在Python中,如何通过字符串动态创建对象并调用其方法?这是一个常见的编程需求,尤其在需要根据配置或运行...

在Linux终端中使用python --version命令时如何解决权限问题? 在Linux终端中使用python --version命令时如何解决权限问题? Apr 02, 2025 am 06:36 AM

Linux终端中使用python...

See all articles