我的网站搭建(第43天) 删除未使用的图片

  • 发布时间:2017年2月13日 11:38
  • 作者:杨仕航
* 该文是基于Python2.7开发的,最新Python3.x和Django2.x视频教程可以前往 >> Django2.0视频教程

自从之前使用了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项目。避免写错代码,删除有被使用的图片。

执行代码,可以看到执行效果。

20170213/20170213113657594.png

一共有369张图片,其中10张图片没有被使用到并删除。

上一篇:Excel绘制心形图(情人节特辑)

下一篇:Django用annotate实现联合统计查询

评论列表

杨仕航

杨仕航

Python的特性使得它经常被用于运维上

2017-02-16 16:13 回复

新的评论

清空