• 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
  • 相关阅读:
    TransactSQL selectCourse storedprocedurestuSysInfo project form cmm
    TransactSQL insert触发器 游标遍历结果集
    css custome checkbox style in sench list
    在ipad的safari上使用Skype链接
    一个async和await 关键字的简单入门
    MVP模式
    c#静态变量和静态属性的区别
    异步延时启动
    C#中 托管线程的状态
    NLog实现归档日志且只保留一段时间的日志(比如一个星期)
  • 原文地址:https://www.cnblogs.com/jl-bai/p/6288218.html
Copyright © 2020-2023  润新知