将验证的错误信息显示到页面
用ajax实现
首先建立一个FormData对象,将data信息append进去.
这里要注意两点:
1.ajax发送时,csrf防护信息也要发送formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
2.如果发送的data中有文件,就需要在ajax的参数中加上processData: false, contentType: false,
数据传到后台之后,处理验证,之后返回data,success接受到data
通过判断data.status判断是否出错:
1.出错,通过$.each
函数将错误显示
2.没出错,显示index页面
html文件
$("#reg-submit").click(function () {
// 取到用户填写的注册数据,向后端发送AJAX请求
var formData = new FormData();
formData.append("username", $("#id_username").val());
formData.append("password", $("#id_password").val());
formData.append("re_password", $("#id_re_password").val());
formData.append("email", $("#id_email").val());
formData.append("avatar", $("#id_avatar")[0].files[0]);
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: "/reg/",
type: "post",
processData: false,
contentType: false,
data: formData,
success:function (data) {
if (data.status){
// 有错误就展示错误
// console.log(data.msg);
// 将报错信息填写到页面上
$.each(data.msg, function (k,v) {
// console.log("id_"+k, v[0]);
// console.log($("#id_"+k));
$("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
})
}else {
// 没有错误就跳转到指定页面
location.href = data.msg;
}
}
})
});
视图函数
需要注意的点:
需要改变status的值,需要给msg赋值,这些都通过ret返回,前端用data接受
# 注册的视图函数
def register(request):
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = forms.RegForm(request.POST)
print(request.POST)
# 帮我做校验
if form_obj.is_valid():
# 校验通过,去数据库创建一个新的用户
form_obj.cleaned_data.pop("re_password")
avatar_img = request.FILES.get("avatar")
models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
ret["msg"] = "/index/"
return JsonResponse(ret)
else:
print(form_obj.errors)
ret["status"] = 1
ret["msg"] = form_obj.errors
print(ret)
print("=" * 120)
return JsonResponse(ret)
# 生成一个form对象
form_obj = forms.RegForm()
print(form_obj.fields)
return render(request, "register.html", {"form_obj": form_obj})
将图片保存在数据库中
首先看看models.py里是怎么设计这个属性的
class UserInfo(AbstractUser):
"""
用户信息表
"""
nid = models.AutoField(primary_key=True)
phone = models.CharField(max_length=11, null=True, unique=True)
avatar = models.FileField(upload_to="avatars/", default="avatars/default.png", verbose_name="头像")
create_time = models.DateTimeField(auto_now_add=True)
blog = models.OneToOneField(to="Blog", to_field="nid", null=True)
def __str__(self):
return self.username
avatar就是头像,他的上传路径是upload_to="avatars/",
,他的默认头像是default="avatars/default.png"
这个时候可能会疑惑,为为什么这个用户信息类没有username,password等字段呢,这是因为这里这些关键字我们用Django自带的验证模块去写了.新建了一个forms.py文件
"""
bbs用到的form类
"""
from django import forms
from django.core.exceptions import ValidationError
# 定义一个注册的form类
class RegForm(forms.Form):
username = forms.CharField(
max_length=16,
label="用户名",
error_messages={
"max_length": "用户名最长16位",
"required": "用户名不能为空",
},
widget=forms.widgets.TextInput(
attrs={"class": "form-control"},
)
)
password = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(
attrs={"class": "form-control"},
render_value=True,
),
error_messages={
"min_length": "密码至少要6位!",
"required": "密码不能为空",
}
)
re_password = forms.CharField(
min_length=6,
label="确认密码",
widget=forms.widgets.PasswordInput(
attrs={"class": "form-control"},
render_value=True,
),
error_messages={
"min_length": "确认密码至少要6位!",
"required": "确认密码不能为空",
}
)
email = forms.EmailField(
label="邮箱",
widget=forms.widgets.EmailInput(
attrs={"class": "form-control"},
),
error_messages={
"invalid": "邮箱格式不正确!",
"required": "邮箱不能为空",
}
)
# 重写全局的钩子函数,对确认密码做校验
def clean(self):
password = self.cleaned_data.get("password")
re_password = self.cleaned_data.get("re_password")
if re_password and re_password != password:
self.add_error("re_password", ValidationError("两次密码不一致"))
else:
return self.cleaned_data
回到视图函数
关键代码:
avatar_img = request.FILES.get("avatar")
得到图片
models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img,phone="123123")
往数据库中插入,这里可以看到,因为form_obj.cleaned_data是froms.py中建立的清洗过的数据,所以这里面不包含其他的UserInfo信息,就要再写一个参数,比如电话(phone)
# 注册的视图函数
def register(request):
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = forms.RegForm(request.POST)
print(request.POST)
# 帮我做校验
if form_obj.is_valid():
# 校验通过,去数据库创建一个新的用户
form_obj.cleaned_data.pop("re_password")
avatar_img = request.FILES.get("avatar")
models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img,phone="123123")
ret["msg"] = "/index/"
return JsonResponse(ret)
else:
print(form_obj.errors)
ret["status"] = 1
ret["msg"] = form_obj.errors
print(ret)
print("=" * 120)
return JsonResponse(ret)
# 生成一个form对象
form_obj = forms.RegForm()
print(form_obj.fields)
return render(request, "register.html", {"form_obj": form_obj})
我们的models.py中的UserInfo表和forms.py中的form注册类共同组成了UserInfo这个表,因为UserInfo继承自,如下:
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
我们看最后生成的表,既有password这些来自forms.py的属性也有phone这些来自UserInfo的属性,还有一些Django验证自带的属性比如is_staff