基于Ajax提交formdata数据、错误信息展示和局部钩子、全局钩子的校验。
formdata重点:
- 实例化FormData这个类
- 循环serializeArray可以节省代码量
- 图片要用$('#id')[0].files[0]来获得
- 加上contentType:false和processData:false
错误信息展示重点:
- input框的id是id_field,可以通过循环错误信息获取错误信息的字段field,然后通过id_filed展示错误信息
- 展示错误信息前先把错误信息清空了
全局钩子重点:
可在前端通过__all__获取全局错误信息并展示出来
html
<div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form id="fm"> {% csrf_token %} {% for field in form %} <div class="form-group"> <label for="{{ field.id_for_label }}">{{ field.label }}</label> {{ field }} <span class="error-info pull-right"></span> </div> {% endfor %} <div class="form-group"> <label for="id_avatar">头像 <img width="60" height="60" id="avatar_img" src="/static/blog/img/default_avatar.jpg"> </label> <input type="file" name="avatar" id="id_avatar" class="hidden"> </div> <input type="button" id="reg_btn" class="btn btn-info" value="提交"> </form> </div> </div> </div>
js
// 头像预览功能 $('#id_avatar').change(function () { // 图片发生了变化,所以要用change事件 // 获取用户选中的文件对象 let file_obj = $(this)[0].files[0]; // 获取文件对象的路径 let reader = new FileReader(); // 等同于在python里拿到了实例对象 reader.readAsDataURL(file_obj); reader.onload = function () { // 修改img的src属性,src = 文件对象的路径 $("#avatar_img").attr('src', reader.result); // 这个是异步,速度比reader读取路径要快, // 所以要等reader加载完后在执行。 }; }); // 基于Ajax提交数据 $('#reg_btn').click(function () { let formdata = new FormData(); // 相当于python里实例化一个对象 let request_data = $('#fm').serializeArray(); $.each(request_data, function (index, data) { formdata.append(data.name, data.value) }); formdata.append('avatar', $('#id_avatar')[0].files[0]); $.ajax({ url: '', type: 'post', contentType: false, processData: false, data: formdata, success: function (data) { if (data.user) { // 注册成功 location.href = '{% url "blog:login" %}' } else { // 注册失败 // 清空错误信息,每次展示错误信息前,先把之前的清空了。 $('span.error-info').html(""); $('.form-group').removeClass('has-error'); // 展示此次提交的错误信息 $.each(data.msg, function (field, error_list) { if (field === '__all__') { // 全局错误信息,在全局钩子里自己定义的 $('#id_re_pwd').next().html(error_list[0]); } $('#id_' + field).next().html(error_list[0]); $('#id_' + field).parent().addClass('has-error'); // has-error是bootstrap提供的 }); } } }) })
regForm.py
""" 用户注册验证 """ from django import forms from django.forms import widgets, ValidationError from blog.models import UserInfo class RegForm(forms.Form): user = forms.CharField( max_length=32, min_length=6, error_messages={ 'required': '用户名不能为空', 'max_length': '用户名长度不能超过32个', 'min_length': '用户名长度不能少于6个', }, label='用户名', widget=widgets.TextInput( attrs={'class': 'form-control'} ) ) pwd = forms.CharField( max_length=32, min_length=6, error_messages={ 'required': '密码不能为空', 'max_length': '密码长度不能超过32个', 'min_length': '密码长度不能少于6个', }, label='密码', widget=widgets.PasswordInput( attrs={'class': 'form-control'} ) ) re_pwd = forms.CharField( max_length=32, min_length=6, error_messages={ 'required': '确认密码不能为空', 'max_length': '密码长度不能超过32个', 'min_length': '密码长度不能少于6个', }, label='确认密码', widget=widgets.PasswordInput( attrs={'class': 'form-control'} ) ) email = forms.EmailField( max_length=32, error_messages={ 'required': '用户名不能为空', 'invalid': '请输入正确的邮箱格式', }, label='邮箱', widget=widgets.EmailInput( attrs={'class': 'form-control'} ) ) def clean_user(self): username = self.cleaned_data.get('user') user = UserInfo.objects.filter(username=username).first() if not user: return username else: raise ValidationError('该用户已注册') def clean(self): pwd = self.cleaned_data.get('pwd') re_pwd = self.cleaned_data.get('re_pwd') if pwd and re_pwd: if pwd == re_pwd: return self.cleaned_data else: raise ValidationError('两次密码不一致')
views.py
from django.contrib import auth from django.shortcuts import render, HttpResponse from django.http import JsonResponse from blog.utils.slide_auth_code import pcgetcaptcha from blog.forms.regForm import RegForm def register(request): if request.is_ajax(): print(request.POST) form = RegForm(request.POST) response = {'user': None, 'msg': None} if form.is_valid(): response['user'] = form.cleaned_data.get('user') else: print(form.cleaned_data) print(form.errors) response['msg'] = form.errors return JsonResponse(response) form = RegForm() context = { 'form': form } return render(request, 'register.html', context=context)