带上传头像注册功能的实现
带上传头像注册功能的实现
注册
注册是每个网站必不可少的一部分,通过注册来增加网站用户。
实现注册功能在 Django 中非常方便,利用 Django 自带的 Form 模块可以快速生成注册用的 Form 表单,利用 Django 自带的 Auth 模块可以自定义用户表的字段。
本文要实现的是通过 AJAX 异步发送数据,带上传头像图片的注册方式。
此时,在 models 数据表、HTML 页面、视图函数都会有一定变化。
models
from django.contrib.auth.models import AbstractUser
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")
create_time = models.DateTimeField(auto_now_add=True)
blog = models.OneToOneField(to="Blog", to_field="nid", null=True)
def __str__(self):
return self.username
首先,为了方便使用 Django 自带的认证系统,用户信息表继承了抽象用户类,此时需要在 setting 中设置次表为默认的认证表。
# 告诉Django项目用哪张表做认证
AUTH_USER_MODEL = 'blog.UserInfo'
其次,重要的是 avatar 字段,是 FileFiled 字段,需要设置文件上传的文件夹和默认的文件。
avatar = models.FileField(upload_to="avatars/", default="avatars/default.png")
HTML 页面
首先是上传图片文件的 input 元素的隐藏和预览,可以参考:注册时头像预览功能的实现
在 form 表单中有上传文件的 input 标签时,需要在 form 标签中设置属性 enctype="multipart/form-data"
重要的点是 AJAX 提交带文件的数据。
// AJAX提交注册的数据
$("#reg-submit").click(function () {
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, // 告诉JQuery不要处理我的数据
contentType: false, // 告诉Jqu不要设置content类型
data: formData,
success: function (data) {
if (data.status) {
// 将错误信息填写到页面上
$.each(data.msg, function (k, v) {
$("#id_" + k).next("span").text(v[0]).parent().parent().addClass("has-error");
})
} else {
// 没有错误就跳转到指定页面
location.href = data.msg
}
}
});
});
注意:
-
因为有文件数据,所以在通过 AJAX 往后端传数据时使用 FormData 对象。
formData.append("avatar", $("#id_avatar")[0].files[0]);
-
因为有文件数据,所以在通过 AJAX 往后端传数据时需要设置以下属性:
processData: false, // 告诉JQuery不要处理我的数据 contentType: false, // 告诉Jqu不要设置content类型
视图函数
def register(request):
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = forms.RegForm(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:
ret["status"] = 1
ret["msg"] = form_obj.errors
return JsonResponse(ret)
form_obj = forms.RegForm()
return render(request, "register.html", {"form_obj": form_obj})
在后端获得上传文件路径的方法:
avatar_img = request.FILES.get("avatar")
在成功上传头像文件后,数据库中头像字段保存的是在后端文件的路径。
avatar_database
GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/s9day76/bbs