[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
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})
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传给前端
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>
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