django练手(二十二):增加删除图片的功能

一、功能描述

  1. 缩略图下面增加图片名称和删除链接;
  2. 点击删除链接发送post请求到后台,并传图片id;
  3. 后台接收到id,把该id图片的is_active值置为false;
  4. 刷新缩略图的div;
  5. 刷新分页区域。

二、功能实现

  1. 修改app-models.py 的avatar类,增加is_active字段,代码如下:
    # 用户图标上传模型
    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)
    
  2. 在app-views-app-account.py 文件中修改avatar_upload方法,获取缩略图数据时增加过滤条件,is_active==True。代码如下:
    # 图标上传
    @login_required
    def avatar_upload(request):
    	if request.method == 'GET':
    		# 获取所有的用户图标数据
    		# avatars = Avatar.objects.filter().all().order_by('-id')
    		avatars = Avatar.objects.filter(is_active=True).order_by('-id')
    		# 注意:Paginator查询集能处理的queryset必须是有序的
    		paginator = Paginator(avatars, 3)
    		# 获浏览器传递的取页码数
    		page_num = request.GET.get('page_num', '')
    
    		# 如果page_num非空且page_num字符串只有数字构成。方法isnumeric() 检测字符串是否只由数字组成。这种方法是只针对unicode对象。
    		if page_num is not None and page_num.isnumeric():
    			page_num = int(page_num)
    		else:
    			page_num = 1
    		if page_num not in paginator.page_range:
    			page_num = 1
    		avatars = paginator.page(page_num)
    		#
    		page_range = paginator.page_range
    		page_range = new_page_range(page_range, page_num)
    
    		return render(request, 'app/avatar.html', {"avatars": avatars, "page_range": page_range})
    	if request.method == "POST":
    		# 1、判断文件路径是否存在,如果不存在,生成文件路径。
    		image_folder_path = os.path.join(settings.MEDIA_ROOT, 'image', 'avatar')  # 文件路径
    		image_folder_path_exists = os.path.exists(image_folder_path)  # 判断文件路径是否存在
    		# 如果不存在,则生成文件路径
    		if not image_folder_path_exists:
    			os.makedirs(image_folder_path)
    		# 获取所有上传的图标
    		file_list = request.FILES.getlist('avatar_upload')
    		if file_list:
    			for file in file_list:
    				# 1、把文件名替换成整个系统唯一的文件名。
    				name = uuid_name(file.name)
    				# 2、获取文件中文名
    				title = os.path.splitext(file.name)[0]
    				# 3、文件存储的位置。
    				file_path = image_folder_path + '\\' + name
    				# 4、把文件写入硬盘
    				with open(file_path, 'wb', ) as f:
    					for part in file.chunks():
    						f.write(part)  # 内容块写入文件
    						f.flush()  # 清除内存
    				# 5、生成存储在数据库里的路径。
    				database_path = 'uploads/image/avatar/' + name
    				# 6、把文件信息写入数据库
    				avatar = Avatar()
    				avatar.title = title
    				avatar.img_url = database_path
    				avatar.save()
    		return JsonResponse({"status": True, })
    
    
  3. 增加删除图片的视图,代码如下:
    # 删除图片的视图
    	def avatar_del(request):
    		"""
    		获取要删除图片的id,通过id获取图片对象,并把该对象的is_active的值改为false
    		"""
    		if request.method == 'POST':
    			avatar_id = request.POST.get('id', '')
    			if avatar_id:
    				avatar_objects = Avatar.objects.filter(id=avatar_id).first()
    				avatar_objects.is_active = False
    				avatar_objects.save()
    				return JsonResponse({"status": True})
    
  4. 前端app-templates-app-avatar.html文件下,增加删除按钮,代码如下:
    	<div class="row" id="avatar">
    				<div id="avatar_child">
    					{% for avatar in avatars %}
    						<div class="col-sm-6 col-md-4">
    							<a href="#" class="thumbnail">
    								<img src="../../../{{ avatar.img_url }}"
    									 alt="{{ avatar.title }}" data-toggle="modal" data-target="#myModal" class="motai">
    							</a>
    							<!--增加的文件名和删除链接-->
    							<p style="text-align: center">{{ avatar.title }} <a href="#" id="{{ avatar.id }}"
    																				class="delImg">删除</a></p>
    						</div>
    					{% endfor %}
    				</div>
    			</div>
    
    效果如下图:
    image
  5. 前端app-templates-app-avatar.html文件下,新增发起ajax请求删除图片的方法。该方法主要有三个功能:
    ①以post方式把图片id传送到后台;
    ②ajax发送成功后刷新图片显示的div;
    ③刷新分页的div;
    代码如下:
    // 删除图片的程序
        function delImgClick() {
            /*
            当id为avatar的div里面的<a>标签被点击时,执行以下几个动作:
            1、获取csrf_token
            2、获取被点击元素的id,这个id是图片在数据库里存储的id
            3、把id和csrf_token组成json格式的数据
            4、向后台发送post形式的ajax,让后台执行删除动作
            5、ajax发送成功后,刷新id为avatar_child的div,刷新分页数据
            * */
            $("#avatar").on("click", "a", function () {
                let CsrfToken = $("[name='csrfmiddlewaretoken']").val();
                let id = $(this).attr("id");
                let data = {'csrfmiddlewaretoken': CsrfToken, "id": id};
    
                $.ajax({
                    url: "{% url 'app:avatar_del' %}",
                    type: "post",
                    data: data,
                    dataType: "json",
                    async: true,
                    success: function (res) {
                        // 删除成功后重新加载图标<div>里面的内容
                        $("#avatar_child").load(location.href + " #avatar_child>*", "");
                        // 删除成功后重新加载分页的内容
                        $("#pagination").load(location.href + " #pagination>*", "");
                    },
                    error: function (res) {
                        console.log("ajax发送失败");
                    }
                })
    
            })
        }
    
    

三、涉及的知识点

  1. Jquery 的on方法:on() 方法在被选元素及子元素上添加一个或多个事件处理程序。
    ①写法:$(selector).on(event,childSelector,data,function)
    ②本节用在:删除按钮的选择。$("#avatar").on("click", "a", function ())
    ③解决的问题:第依次删除后,刷新图片区域div,点击其它图片的删除按钮,不起作用的问题。

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

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