django模型上传图片后修改/删除图片服务器操作小结
2018-11-08 本文已影响303人
PeterPZ
在项目中遇到相应的需求,各路搜寻解决方法,以记之。
实际项目中,用户长期上传图片(头像、信息)等存入服务器,服务器资源有限就需要定时去清理,手动清理未过于麻烦,所以需要再删除操作时将与之对应在服务上的文件一并删除,修改操作亦是如此,在修改时将原来的文件删掉,重新上传新文件到服务器。
django里对于文件、图片等有与之对应的模型models.FileField(),models.ImageField()用起来相当方便,但当我从admin中删除一个条目,服务器上的实际文件不会删除。查阅多方资料实验和总结出两种解决方案:
第一种直接在models中定义删除方法并指定信号源model,这样在进行删除操作时会将model对应上传的服务器上的文件一并删除;
第二种就是自己写一个delete方法python脚本,在进行删除操作时ssh连接远端服务器,执行shell命令删除指定地址的文件。
相对来说第一种实现起来更简便一些,但第二种可以更方便的做定制,例如定时操作及修改操作删除旧的文件,但弊端就是在执行操作时都需要进行ssh连接服务器,对于后续维护来说有一些麻烦。
一、在models中接收pre_delete信号并调用FileField对象上的delete方法
在models中
导入 pre_delete 和 receiver这两个包
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
并指定pre_delete信号源model
class MyModel(models.Model):
file = models.FileField()
...
# Receive the pre_delete signal and delete the file associated with the model instance.
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
@receiver(pre_delete, sender=MyModel)
def mymodel_delete(sender, instance, **kwargs):
# Pass false so FileField doesn't save the model.
instance.file.delete(False)
二、单独在python脚本中定义delete方法
利用一个python的模块paramiko
Paramiko
paramiko模块,基于SSH用于连接远程服务器并执行相关操作。
安装
pip3 install paramiko
定义删除方法 delete_file,传入文件绝对地址file_path
# 删除服务器上文件
def delete_file(file_path):
"""
删除文件 root权限
"""
try:
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname="127.0.0.1", port=22, username="peter", password="784504405")
command = 'rm -f ' + file_path
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command, get_pty=True)
print(stderr.read())
ssh.close()
msg = '对应文件也删除!'
return msg
except Exception as e:
return str(e)