关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
自从之前使用了django-ueditor富文本编辑器编辑博文,上传图片等操作变得很轻松。
有时上传了一张图片发现截图没有截好,删掉再重新上传。
但这个删除操作不会删掉服务器中已经上传的图片。久而久之,这种垃圾图片会越来越多,占用服务器的空间。
若人工检查,也不靠谱。费时费力且容易出错。
这种重复的工作就交给代码处理。Python可用于运维,写个Python脚本处理。
在我们的Django根目录下创建一个py文件,del_imgs.py。
因为我们这个脚本有区别于命令行shell模式。需要通过django加载我们的项目。如下代码:
#coding:utf-8 import django import os def load_setting(): #设置settings文件的位置(yshblog换成具体的项目名称) os.environ['DJANGO_SETTINGS_MODULE'] = 'yshblog.settings' django.setup() #加载yshblog项目
加载Django项目之后,即可操作和访问数据。
那么,我们如何判断资源文件夹中的图片是否没有被使用?
我的思路如下:
1)找到博文使用图片所在的目录
2)提取该目录下的所有图片
3)根据图片名或图片路径判断在博文的内容中是否出现
4)若出现,说明被使用
5)若从未出现,说明未被使用,删除之
首先,先找到博文使用图片所在的目录。
由于我的博文所使用图片都放在一个目录下,相当容易获取。这个需要根据自己项目具体情况处理。我获取目录的代码如下:
from django.conf import settings #通过STATICFILES_DIRS获取静态目录列表,这个需要根据自己项目设置路径 img_folder = os.path.join(settings.STATICFILES_DIRS[0], 'media', 'article')
其次,获取目录下的图片。
由于我的博文使用图片的图片名称都不一样,所以可以只获取图片名称即可。
这里有两种方法,选其一即可。
#遍历目录中的文件和文件夹 for root, dirs, files in os.walk(img_folder): #遍历文件列表 for filename in files: #通过后缀名判断是否是图片 if os.path.splitext(filename) in ['.jpg', '.png', '.gif']: pass
还有一种,用fnmatch库模式匹配。
import fnmatch #模式匹配列表,*号表示多个字符,?号表示1个字符 patterns = ['*.jpg', '*.png', '*.gif'] #遍历目录中的文件和文件夹 for root, dirs, files in os.walk(img_folder): #遍历多个模式表达式 for pattern in patterns: #通过模式表达式查找符合条件的文件 for filename in fnmatch.filter(files, pattern): pass
获取到图片文件名之后,需要打开博文的模型对象,判断内容是否包含该图片名称。可用如下代码查询。
#加载Blog模型 from blog.models import Blog #判断文件是否被使用(content字段是否包含filename) if Blog.objects.filter(content__contains = filename).count() == 0: img_path = os.path.join(root, filename) #若未被使用,则删除 os.remove(img_path)
完整代码如下:
#coding:utf-8 #删除没有使用到的图片 import django from django.conf import settings import os import fnmatch def load_setting(): os.environ['DJANGO_SETTINGS_MODULE'] = 'yshblog.settings' django.setup() #设置为False,避免出现模型查询输出SQL语句 settings.DEBUG = False def main(): #加载django配置 load_setting() from blog.models import Blog #获取静态目录的位置(根据自己项目设置路径) img_folder = os.path.join(settings.STATICFILES_DIRS[0], 'media', 'article') #查找该目录下的图片文件 patterns = ['*.jpg', '*.png', '*.gif'] imgs_del = 0 imgs_count = 0 for root, dirs, files in os.walk(img_folder): for pattern in patterns: for filename in fnmatch.filter(files, pattern): #判断文件是否被使用(content字段是否包含filename) if Blog.objects.filter(content__contains = filename).count() == 0: img_path = os.path.join(root, filename) os.remove(img_path) imgs_del += 1 imgs_count += 1 print('has %s images, delete %s images' % (imgs_count, imgs_del)) if __name__ == '__main__': main()
注意,执行该脚本之前,先保存备份Django项目。避免写错代码,删除有被使用的图片。
执行代码,可以看到执行效果。
一共有369张图片,其中10张图片没有被使用到并删除。
杨仕航
Python的特性使得它经常被用于运维上
2017-02-16 16:13 回复