在我当前的项目中,我将图像存储在 s3 存储桶中。 我有一个 pre_save 信号接收器,用于从 Image 类的 s3 存储桶中删除实际图像。
class Image(models.Model):
name = models.CharField(max_length = 255)
caption = models.CharField(max_length = 255)
image = models.ImageField(upload_to='uploads/',blank=True,null=True)
rent_property = models.ForeignKey(RentProperty, related_name='Images')
is_main_image = models.BooleanField(default=False)
@receiver(models.signals.pre_save, sender=Image)
def auto_delete_file_on_change(sender, instance, **kwargs):
"""Deletes file from filesystem
when corresponding `MediaFile` object is changed.
"""
if not instance.pk:
return False
try:
old_file = Image.objects.get(pk=instance.pk).image
except Image.DoesNotExist:
return False
new_file = instance.image
if not old_file == new_file:
old_file.delete(save=False)
我的问题是,我正在使用 django-rest-framework,我想让 PATCH 工作。但是如果我尝试修补图像描述,它会删除图像本身。我的问题是,我如何编写一个 IF 来区分天气,补丁中是否有需要更改的新图像,如果没有,什么都不做?
请您参考如下方法:
对于带有 ImageField 或 FileField 的模型,我添加了一个附加字段来存储 SHA-1 哈希字符串。我发现这很有用,原因有很多:
- 减少同一文件的不必要传输以进行更新(您的情况)
- 防止用户上传重复文件作为新实例
- 在下载文件时向用户提供 SHA-1 哈希,以便他们验证下载
- 在后端文件系统上进行数据完整性检查以验证文件没有更改
我还保存了原始文件名,以便为面向用户的查看/下载重现它。通过这种方式,后端名称对用户来说无关紧要。
这是基于您的模型的基本实现:
import hashlib
from django.core.exceptions import ValidationError
from django.core.files import File
from django.db import models
class Image(models.Model):
name = models.CharField(max_length = 255)
caption = models.CharField(max_length = 255)
image = models.ImageField(upload_to='uploads/',blank=True,null=True)
original_filename = models.CharField(
unique=False,
null=False,
blank=False,
editable=False,
max_length=256)
sha1 = models.CharField(
unique=True,
null=False,
blank=False,
editable=False,
max_length=40)
rent_property = models.ForeignKey(RentProperty, related_name='Images')
is_main_image = models.BooleanField(default=False)
def clean(self):
"""
Overriding clean to do the following:
- Save original file name, since it may already exist on our side.
- Save SHA-1 hash and check for duplicate files.
"""
self.original_filename = self.image.name.split('/')[-1]
# get the hash
file_hash = hashlib.sha1(self.image.read())
self.sha1 = file_hash.hexdigest()
# Check if this file has already been uploaded,
# if so delete the temp file and raise ValidationError
duplicate_hashes = Image.objects.all().exclude(
id=self.id).values_list('sha1', flat=True)
if self.sha1 in duplicate_hashes:
if hasattr(self.image.file, 'temporary_file_path'):
temp_file_path = self.image.file.temporary_file_path()
os.unlink(temp_file_path)
raise ValidationError(
"This image already exists."
)
