[oldboy-django][2深入django]Form组件功能: 数据格式验证 + 保留上次输入的值

1 需求:登录或者注册页面存在以下问题

- 无法记住上次提交的内容,(如果有很多输入项,这样正确项不必重复输入,错误项也能提示错误信息)
- 重复进行提交数据的校验(数据是否为空,长度大小等等)

2 django的Form组件实现

  2.1 Form组件实现数据验证方法   

    2.1.1 流程操作

        - 定义规则(数据的格式,字段必须和表单上name属性一致)
            class LoginForm(Form):
                字段名 = fields.xxFields(参数) # 定义了一个输入框的数据格式要求
            
            实例化对象obj = LoginForm(request.POST)

        - 数据检验
            obj.is_valid()

        - 提供详细错误信息(可以自定制错误提示)
            -- 自定制错误信息,在类定义的时候通过error_messages参数
            obj.errors

        - 提供符合规则的信息(类型是字典,数据库orm操作支持类型是字典操作)
            obj.cleaned_data
View Code

    2.1.2 实例

- Form提交(提交页面就会刷新,不保留上次输入内容)
                - 流程
                    a.写类LoginForm(Form):
                        字段名 = fields.xxFields() # 验证规则,本质是正则表达式(fields.xxFields()是一个正则表达式)
                        字段名 = fields.xxFields() # 验证规则,本质是正则表达式
                    b. obj = LoginForm(request.POST)
                    c. 验证数据result = obj.is_valid()
                    d. 拿到符合格式的数据 obj.cleaned_data
                    e. 不符合格式,获取错误信息 obj.errors

                - 内部原理
                    """
                        obj.is_valid()执行
                        1 LoginForm(request.POST)实例化时
                            self.fields = {
                                'username': 正则表达式,
                                'password': 正则表达式,
                            }
                        2 循环self.fields
                            flag = True
                            cleaned_data = {}
                            errors = {}
                            for k,v in self.fields.items():
                                #1 k = 'username', v = 正则表达式
                                #2 k = 'password', v = 正则表达式
                                input_value = request.POST.get(k)
                                if re.match(input_value, v):
                                    flag = True
                                else:
                                    flag = False
                            return flag

                    """

                - Form提交数据验证程序(没有实现保留上次输入的值)
                    # 前端
                        <form action="/app02/login" method="POST">
                            {% csrf_token %}
                            <p>
                                <input type="text" name="user" placeholder="用户名">
                                <span style="color:red;">{{ error.user.0 }}</span>
                            </p>
                            <p>
                                <input type="password" name="pwd" placeholder="密码">
                                <span style="color:red;">{{ error.pwd.0 }}</span>
                            </p>
                            <p><input type="submit" value="提交"></p>
                        </form>

                    # LoginForm类
                    class LoginForm(Form):
                        user = fields.CharField(required=True,
                                                error_messages={
                                                        'required': '不能为空',
                                                    })
                        pwd = fields.CharField(required=True,
                                               min_length=8,
                                               error_messages={
                                                        'required': '不能为空',
                                                        'min_length': '长度必须大于8'
                                                    })


                    # 视图
                    def login(request):
                        if request.method == 'GET':
                            return render(request, 'app02_login.html')
                        else:
                            obj = LoginForm(request.POST)
                            # 检验提交数据是否符合规则
                            if obj.is_valid():
                                print(obj.cleaned_data)
                                # obj.cleaned_data是一个字典,form表单提交的数据
                                #{'password': 'aaaaaaaaaa', 'username': 'alexadfdda'}
                                return redirect('/app02/login')
                            else:
                                return render(request, 'app02_login.html', {'error': obj.errors})
View Code

    2.1.3 缺点

      一点提交,页面就会刷新,不能保留上次输入的数据

  2.2 Form组件实现保留上次输入方法

    2.2.1原理:利用Form组件能够生成html标签来实现

                a.原理: 利用Form组件可以生成标签
                    GET:
                        obj = TestForm()
                        {{ obj.t1 }} 等效成 <input type="text" name="t1">
                    POST:
                        obj = TestForm(request.POST)
                        {{ obj.t1}} 等效成<input type="text" name="t1" value = "你提交的数据">
                    
                     总之, 前端:{{ obj.t1 }}或者 {{obj.as_p}}
                            视图:无论get还是Post都将obj传给前端
View Code

    2.2.2实例

                b.实例
                    # FormL类
                    class TestForm(Form):
                        t1 = fields.CharField(
                            required=True,
                            min_length=4,
                            max_length=8,
                            widget=widgets.TextInput,
                            label='用户名',
                            label_suffix=':',
                            help_text='4-8个字符',
                            initial='root'
                        )
                        t2 = fields.CharField(
                            required=True,
                            min_length=8,
                            widget=widgets.PasswordInput,
                            label='密码',
                            label_suffix=':',
                            initial='password'
                        )
                    #视图
                        def test(request):
                            if request.method == 'GET':
                                obj = TestForm()
                                return render(request, 'app02_test.html', {'obj': obj})
                            else:
                                obj = TestForm(request.POST)
                                if obj.is_valid():
                                    # 数据库添加数据
                                    return redirect("/app02_index.html")
                                else:
                                    return render(request, 'app02_test.html', {'obj': obj})

                    # 前端
                        <form action="/app02/test" method="POST" novalidate>
                            {% csrf_token %}
                            {{ obj.as_p }}
                            <p><input type="submit" value="提交"></p>
                        </form>


            3 补充
                有些浏览器会对Input首先做了验证,所以要先对form表单剔除掉浏览器的验证
                <form novalidate>
View Code

 

3 补充ajax实现需求:数据验证+保留上次输入的值

  3.1 原理:

    因为ajax提交数据不会刷新页面,所以主要实现数据验证(Form实现)+ 错误信息提示  

  3.2 实例

- ajax提交(能验证数据 + 保留上次输入的值)
                # 模板
                    <form action="/app02/ajax_login" method="POST" id="form1">
                        {% csrf_token %}
                        <p>
                            <input type="text" name="user" placeholder="用户名">
                            <span style="color:red;">{{ error.user.0 }}</span>
                        </p>
                        <p>
                            <input type="password" name="pwd" placeholder="密码">
                            <span style="color:red;">{{ error.pwd.0 }}</span>
                        </p>
                        <p><a onclick="submitForm();">ajax提交数据</a></p>
                    </form>
                    <script src="/static/js/jquery-1.12.4.js"></script>
                    <script>
                        function submitForm() {
                            $(".temp").remove();
                            $.ajax({
                                url: '/app02/ajax_login',
                                type: 'POST',
                                data: $('#form1').serialize(),
                                dataType: 'JSON',
                                success: function (arg) {
                                    console.log(arg);
                                    if(arg.status){

                                    }else{
                                        $.each(arg.msg, function (index, value) {
                                            tag = document.createElement('span');
                                            tag.innerHTML = value[0];
                                            tag.style.color = 'red';
                                            tag.className = "temp";
                                            $('#form1').find('input[name="' + index + '"]').after(tag);

                                        })

                                    }
                                }
                            })
                        }
                    </script>

                # 视图
                def ajax_login(request):
                    if requset.method = 'GET':
                        return render(request, 'ajax_login.html')
                    else:
                        ret = {'status': True, 'msg': None}
                        obj = LoginForm(request.POST)
                        if obj.is_valid():
                            print(obj.cleaned_data)
                        else:
                            ret['status'] = False
                            ret['msg'] = obj.errors
                        import json
                        return HttpResponse(json.dumps(ret))
                        # 可以返回render, 因为render实际就是调用HttpResponse
View Code

 

  

 

 

posted @ 2017-11-19 10:04  liuzhipenglove  阅读(551)  评论(0编辑  收藏  举报