django练手(二十三):增加用户选择自己头像的功能
一、实现思路
- 用户点击头像框,弹出模态框。模态框里的内容是供用户选择的头像。
- 用户点击模态框中的图片,被点击图片地址传递给用户头像框中的图片。
- 模态框隐藏。
- 被点击图片的id被传到后台。
- 后台接收到图片id,把该id写入用户表对应的图片id位置。
- 用户再次访问该页面时,从数据库取头像路径,在前台显示。
二、具体实现
- 修改图标模型和用户模型。用户模型新增“avatar”字段,该字段是“Avatar”模型的外键。代码如下:
# 用户图标模型 class Avatar(models.Model): # 图标名称 title = models.CharField(max_length=30, verbose_name='图片名称', help_text='图片名称,超过30个字会被截断') # 上传时间 time = models.DateTimeField(auto_now_add=True, help_text='图片上传时间') # 图片路径 img_url = models.CharField(max_length=300, verbose_name='图片路径') # 是否删除 is_active = models.BooleanField(default=1) # 在AbstractUser的基础上,给用户模型扩展两个字段:电话号码和地址 class MyUser(AbstractUser): phone_num = models.CharField(max_length=11, verbose_name='手机号', help_text='手机号是必填项') address = models.CharField(max_length=100, verbose_name='地址', blank=True, help_text='请输入地址') avatar = models.ForeignKey(to=Avatar, verbose_name='头像', blank=True, null=True, on_delete=models.DO_NOTHING)
- 前端部分
新建app-templates-app下新建userinfo.html文件。里面的代码如下:{% extends 'app/layout/basic.html' %} {% load static %} {% block css %} <style> .user_img { width: 56px; height: 56px; border: #f0f0f0 solid; padding: 0; } img { width: 50px; height: 50px; margin: 0; } </style> {% endblock %} {% block content %} {% csrf_token %} <div class="user_img" data-toggle="modal" data-target="#myModal" id="user_img_div"> <!--用户图标的显示位置,初始的图片路径是数据库用户表中的图片路径。当用户选择图片后,被选择图片的路径传给这个图片--> <img src="../../../{{ user_img_url }}" alt="" id="user_img"> </div> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-body"> <!--模态框里面的用户图标展示--> {% for avatar in avatars %} <img src="../../../{{ avatar.img_url }}" alt="{{ avatar.title }}" id="{{ avatar.id }}"> {% endfor %} </div> </div> </div> </div> {% endblock %} {% block js %} <script> /* 当模态框里的图片被单击的时候: 1、被单击图片的路径赋给用户图标的图片; 2、模态框隐藏; 3、被单击图片的id和csrf_token组成data,通过ajax的data方法发送到后台。 */ $('.modal-body').on('click', 'img', function () { let img_src = $(this).attr("src"); $("#user_img").attr("src", img_src); $("#myModal").modal('hide'); let id = $(this).attr("id"); let CsrfToken = $("[name='csrfmiddlewaretoken']").val(); let data = {'csrfmiddlewaretoken': CsrfToken, "avatar_id": id}; $.ajax({ url: "{% url 'app:userinfo_edit' %}", type: "POST", // data: {"avatar_id": id}, data: data, dataType: "json", success: function (res) { if (res.status) { console.log("头像成功保存") } else { console.log(res.message) } }, error: function (res) { console.log("发送失败"); } }) }) </script> {% endblock %}
- 在app-views-app-account.py文件中新建userinfo_edit方法,处理前台发送过来的图片id,代码如下:
# 编辑用户信息(目前只有用户选择图标的功能) @login_required def userinfo_edit(request): """ 1、如果是GET的访问方式,则在数据库中取得所用图标数据。 2、在GET的访问方式下,如果用户是登录状态,则在数据库中取得该用户图标的url,并和所有图标数据一起返回到前端。 3、在GET的访问方式下,如果用户是未登录状态,则只把所有图标数据返回给前端。 4、如果是POST的访问方式,从POST数据中获取图标的id。 5、如果图标id存在,且用户是登录状态,则把图标id保存到用户信息中,并把状态为真的值返回前端。 6、如果图标id不存在,或者用户没有登录,则把状态为False的值和错误信息返回前端。 """ if request.method == 'GET': # 获取所有的用户图标数据 avatars = Avatar.objects.filter(is_active=True).order_by('-id') # 如果当前用户是登录状态,获取当前用户的图标地址,并把所有用户图标地址返回到前端 if request.user.username: avatar_id = request.user.avatar_id user_img_url = Avatar.objects.filter(id=avatar_id).first().img_url return render(request, 'app/userinfo.html', {"avatars": avatars, "user_img_url": user_img_url}) else: return render(request, 'app/userinfo.html', {"avatars": avatars}) if request.method == 'POST': # 获取图标ID avatar_id = request.POST.get("avatar_id", "") if avatar_id and request.user.username: # 把图标ID赋值给用户的图标ID字端,并保存 request.user.avatar_id = avatar_id request.user.save() return JsonResponse({"status": True}) else: return JsonResponse({"status": False, "message": "用户没有登录,无法保存"})
- 路由配置。
在app-urls.py中新增一条路由,指向第3步的视图,具体代码如下:urlpatterns = [ path('register/', register, name='register'), # 注册的路由 path('login/', login_view, name='login'), # 登录的路由 path('logout/', auth_logout, name='logout'), # 注销的路由 path('changepwd/', change_password, name='change_password'), # 修改密码的路由 path('avatar/', avatar_upload, name='avatar_upload'), # 用户图标上传 path('delavatar/', avatar_del, name='avatar_del'), # 删除用户图标 path('userinfo/', userinfo_edit, name='userinfo_edit') # 编辑用户信息 ]
三、效果如下图
本节代码已上传至gitee.com。仓库地址是:https://gitee.com/yanfenglucky/bokeyuan