zoukankan      html  css  js  c++  java
  • Django form表单的校验、局部钩子及全局钩子

    #form表单的校验、局部钩子及全局钩子#

    ## views.py 视图函数 ##

    from django import forms                #调用forms模块
        from django.forms import widgets        #调用widgets模块,用来对form组件的参数配置。
        from django.core.exceptions import ValidationError  #调用 ValidationError 模块。用来手动触发raise错误。
        from fileupdate.models import *      #载入必要的数据库列表。
    
    
        class FormReg(forms.Form):
    
            name = forms.CharField(min_length=4, widget=widgets.TextInput(attrs={'class': 'form-control '}), label='姓名',
                                   error_messages={'required': '*不能为空', })
            pwd = forms.CharField(min_length=4, widget=widgets.PasswordInput(attrs={'class': 'form-control'}), label='密码')
            r_pwd = forms.CharField(min_length=4, widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                                    label='确认密码')
            email = forms.EmailField(widget=widgets.EmailInput(attrs={'class': 'form-control'}), label='邮箱')
            tel = forms.CharField(max_length=13, label='电话', widget=widgets.TextInput(attrs={'class': 'form-control'}))
            ##字段的校验,通过对widget的属性设置,可定义INPUT标签的type类型,以及标签的其他属性。通过对label设置,可以自定义form渲染时的标签名,
            ##另外,通过对error_messages属性设置,可对验证信息进行自定义。注意:字典中错误信息的key值是固定的
        
            def clean_name(self):    #局部钩子   注意:名字必须为clean_%s ,这是根据源码来设置的。
                                    #其原理是,当字段校验完毕后,再进行查找是否有以clean_开头的函数名,如果有,就调用该函数,
                                    #运行我们自定义的函数,如果满足条件就返回当前被校验字段的内容。否则手动触发ValidationError错误,源码中会捕获并将值返回。
                val = self.cleaned_data.get('name')     #通过cleaned_data获得对应字段的'干净数据'
                user_obj = User.objects.filter(name=val).first()  #与对应的数据库中字段相比较,并获得一个字段对象
                if not user_obj:   #对字段进行判断,如果为空(数据库中没有对应的名字),那么返回这个校验值。
                    return val
                else:
                    raise ValidationError('名字存在')   #如果存在,那么手动触发异常(异常名为ValidationError),并设置自定义内容。
        
            def clean(self):   #全局钩子  注意:名字必须为clean,这是根据源码来设置的。
                             #其原理是对校验完毕的字段,再进行字段间的校验。当字段校验完毕,查找是否有clean的函数,如果有就运行该
                             #函数,其功能是对所有校验的字段进行校验比对。如果满足条件,就将cleaned_data返回(这与源码相匹配)
                             #如果不满足就手动触发ValidationError错误。
                pwd = self.cleaned_data.get('pwd') 
                r_pwd = self.cleaned_data.get('r_pwd')
                if pwd and r_pwd:   #如果两个字段中一个为空值那么就不用再进行校验。直接返回cleaned_data,通过校验功能返回错误信息。
                    if pwd == r_pwd:
                        return self.cleaned_data
                    else:
                        raise ValidationError('两次密码不一致!')
                else:
                    return self.cleaned_data
    
        def reg(request):
        
            if request.method == 'POST':  #如果是一次POST提交,那么进行校验。
                formreg = FormReg(request.POST)  #对提交的信息实例化。
        
                if formreg.is_valid():  #通过is_valid()方法进行判断,(注意:当执行这个函数时,将对所有字段进行校验,运行局部钩子和全局钩子)
                    return HttpResponse('OK')
                else:
                    print('cleaneddata', formreg.cleaned_data)
                    print('errordata', formreg.errors)
                    error = formreg.errors.get('__all__') #当设置了全局钩子时,要设置一个变量来获得全局钩子返回的错误信息。
                                #这是由于,全局钩子的错误在form对象的errors中,当clean()方法抛出异常时,源码会自动捕获,并将错误
                                #存储在errors字典中,其中键名'__all__'就是全局钩子的变量。
                    return render(request, 'reg.html', locals())
        
            formreg = FormReg()   #当为get请求时,实例化一个空的对象,通过这个空的实例化对象可以渲染前段,自动生成form表单。
            return render(request,'reg.html', locals())

    ## reg.html 前端页面 ##

      <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>reg</title>
            <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
                  integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        </head>
        <body>
        <div class="container">
            <div class="row">
                <div class="col-md-6 col-md-offset-3">
                    <form action="" method="post" novalidate>
                        {% csrf_token %}
                        {% for field in formreg %}
                            <p>
                                <label for="">{{ field.label }}</label>
                            {{ field }} 
                                {% if field.name == 'r_pwd' %}
                                    <span style="color: crimson">{{ field.errors.0 }} {{ error.0 }}</span>
                                {% else %}
                                    <span style="color: crimson">{{ field.errors.0 }}</span>
                                {% endif %}
        
                            </p>
                        {% endfor %}
        
                        <p><input type="submit"></p>
                    </form>
                </div>
            </div>
        </div>
        
        </body>
        </html>
    View Code
  • 相关阅读:
    在Eclipse中使用JUnit4进行单元测试(上)
    SVN和Subclipse安装和使用指南汇总
    在windows下搭建SVN服务器
    学会SVN的应用源代码托管
    SVN中检出(check out) 和 导出(export) 的区别
    .NET平台三层应用程序框架搭建(一)
    Winform dataGridview 为每一个单元格制定一个tooptip
    SQL row_number() over() 来自动产生行号
    Winform datagridview 设置单元格为只读属性
    SQL 把字符创分割成两个字符串
  • 原文地址:https://www.cnblogs.com/sly27/p/10167332.html
Copyright © 2011-2022 走看看