django练手(二十三):增加用户选择自己头像的功能

一、实现思路

  1. 用户点击头像框,弹出模态框。模态框里的内容是供用户选择的头像。
  2. 用户点击模态框中的图片,被点击图片地址传递给用户头像框中的图片。
  3. 模态框隐藏。
  4. 被点击图片的id被传到后台。
  5. 后台接收到图片id,把该id写入用户表对应的图片id位置。
  6. 用户再次访问该页面时,从数据库取头像路径,在前台显示。

二、具体实现

  1. 修改图标模型和用户模型。用户模型新增“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)
    
    
  2. 前端部分
    新建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 %}
    
  3. 在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": "用户没有登录,无法保存"})
    
    
  4. 路由配置。
    在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')  # 编辑用户信息
    
    ]
    

三、效果如下图

image
本节代码已上传至gitee.com。仓库地址是:https://gitee.com/yanfenglucky/bokeyuan

posted @ 2024-01-14 11:24  喜气洋洋白云山  阅读(59)  评论(0编辑  收藏  举报