IT资讯您现在的位置:主页 > IT资讯 >

Python中form表单的验证

发布日期:2018-01-10 14:48

在编程的过程中,经常会出现form表单的验证问题,西安Java培训整理的相关的form表单验证知识供大家参考。
1. 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的运用
2.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])
错误信息我们能够经过 模板烘托回前端页面,例
{% csrf_token %}
            {#接纳后台传过来的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>
3.自生成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>
4.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