用Ajax提交用户的注册信息(用户名,密码,确认密码,年龄),提交的数据格式为json。用form组件做认证和数据校验,姓名要大于4位,小于16位,并且不能以sb开头和结尾,用户名如果存在,返回用户存在;密码(最大16位,最小8位);年龄,大于18岁,小于100岁,密码和确认密码一致,校验不通过返回错误信息,校验通过,存到user表中。
# 前端代码
<form id="myform">
{% csrf_token %}
{% for userinfo in myforms_obj %}
<p>
<lable for="{{ form.auto_id }}">{{ userinfo.label }}</lable>
<span>{{ userinfo }}</span>
<span style="color: red"></span>
</p>
{% endfor %}
</form>
<input type="button" class="btn btn-primary pull-right" value="注册" id="id_commit">
</body>
<script>
$('#id_commit').click(function () {
// 通过属性选择器选择到性别value
let gender_Val = $(':checked').val()
console.log(gender_Val)
// 3.发送ajax请求
$.ajax({
url: "",
type: 'post',
headers: {'X-CSRFToken': $('input[name=csrfmiddlewaretoken]').val()},
data: JSON.stringify({
'username': $('#id_username').val(),
'age': $('#id_age').val(),
'password': $('#id_password').val(),
'confirm_pwd': $('#id_confirm_pwd').val(),
'gender': gender_Val
}),
// 指定数据格式为json
contentType: 'application/json',
success: function (args) {
if (args.code == 1000) {
alert('提交成功')
// 跳转到url指定页面
window.location.href = args.url
} else {
// 如何将对应的错误提示展示到对应的input框下面
// forms组件渲染的标签的id值都是 id_字段名
$.each(args.msg, function (index, obj) {
console.log(index, obj) // username ["用户名不能为空"]
let targetId = '#id_' + index;
$(targetId).parent().next().text(obj[0]) // 查找错误信息标签
})
}
}
})
})
</script>
# views代码
class Validator(forms.Form):
username = forms.CharField(max_length=16, min_length=4, label='用户名',
error_messages={
'max_length': '用户名过长',
'min_length': '用户名过短',
'required': '请输入用户名'
},
# widget=widgets.TextInput(attrs={"class": "form-control"})
)
age = forms.IntegerField(label='年龄',
error_messages={'required': '请输入年龄后提交'},
# widget=widgets.TextInput(attrs={"class": "form-control"})
)
password = forms.CharField(max_length=16, min_length=8, label='密码',
error_messages={
'max_length': '密码名过长',
'min_length': '密码至少八位',
'required': '请确认密码'
},
# widget=widgets.PasswordInput(attrs={"class": "form-control"})
)
confirm_pwd = forms.CharField(max_length=16, min_length=8, label='确认密码',
error_messages={
'max_length': '密码名过长',
'min_length': '密码至少八位',
'required': '请确认密码'
},
# widget=widgets.PasswordInput(attrs={"class": "form-control"})
)
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
# 局部钩子
def clean_username(self):
username = self.cleaned_data.get('username')
if 'sb' in username:
self.add_error('username', '含有sb是不可以的')
user_obj = models.UserInfo.objects.filter(username=username).first()
if user_obj:
self.add_error('username', '这个用户已经存在')
return username
# 全局钩子
def clean(self):
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_pwd')
if not password == confirm_password:
self.add_error('confirm_pwd', '2次密码输入不一致!')
age = self.cleaned_data.get('age')
if not age in range(18,100):
self.add_error('age', '年龄在18岁到100岁之间')
return self.cleaned_data
from app01 import models
from django.http import JsonResponse
import json
# 信息认证保存
def validator(request):
back_dic = {'code': '', 'msg': ''}
myforms_obj = Validator()
if request.method == 'POST':
data = json.loads(request.body)
myforms_obj = Validator(data)
if myforms_obj.is_valid():
data = myforms_obj.cleaned_data
data.pop('confirm_pwd')
back_dic['code'] = 1000
back_dic['url'] = 'http://www.baidu.com'
models.UserInfo.objects.create(**data)
else:
back_dic['code'] = 2000
back_dic['msg'] = myforms_obj.errors
return JsonResponse(back_dic)
return render(request, 'validator.html', locals())
# models模块
class UserInfo(models.Model):
username = models.CharField(max_length=16,verbose_name='用户名')
password = models.CharField(max_length=16,verbose_name='密码')
age = models.IntegerField(default=18)
gender_choice = ((1,'男'),(2,'女'),(3,'保密'))
gender = models.IntegerField(verbose_name='性别',choices=gender_choice,default=1)
# forms组件的使用流程
导入forms模块和widgets模块:from django import forms from django.forms import widgets
利用form.需要生成的字段名 生成字段forms字段
前端渲染,需要在后端views当中生成一个forms空对象,用于渲染出页面,这里提前可以定义好错误信息怎么渲染,注意错误信息的提示是errors.0,因为返回的错误信息是一个列表
对于默认的校验规则不满足使用要求,可以使用全局钩子(clean)和局部钩子(clean_校验字段名)去自定义校验规则,将错误信息添加到错误的容器当中。
# 对于需要注意的点:
1. 需要传递json数据的时候,修改数据编码格式: contentType: 'application/json',传递的数据也放在了request.body当中;
2.如果有文件对象,可以借助Formdata对象进行传递;
3.csrf_token的值可以放在头当中;
4.传递到后端的数据需要用json模块反序列化得到字典数据进行校验;
5.对于钩子函数,局部钩子函数是将勾出来的数据进行返回;全局钩子函数是返回self.cleaned_data
对于forms组件的常用字段请查看博文:https://www.cnblogs.com/Ailewent/articles/14218728.html,个人总结,总结不到位的地方请多多指教