Django模型中手动触发图片保存方法
Manually trigger image save method in Django model
我有一个带有自定义图像字段的 Django 模型。图像字段在上传时创建一些缩略图大小。代码可能如下所示:
from django.db import models
from utils import CustomImageField
class Photo(models.Model):
image = CustomImageField()
现在我修改原始图像,假设我旋转了它。现在我想再次触发图像字段的保存方法,以覆盖缩略图并创建旋转版本。因此,我不需要在我的代码中的其他地方旋转缩略图 (DRY)。
有什么想法吗?符合这些思路 - 但究竟如何?
p = Photo.objects.get(pk=1)
p.image.save(...)
我可以完全控制 CustomImageField
小部件。 save()
方法定义为:
def save(self, name, path, save=True):
问题是,方法参数使用什么?
一个选项是手动检查脏字段(请参阅此 SO question) or using a pypi package
或者,如果您想节省内存,可以从字段的 属性 setter 触发调整大小(假设您继承自 FileField
class CustomImageField(FileField):
def _set_file(self, file):
has_file_changed = file != self._file
super(CustomImageField, self)._set_file(file)
if has_file_changed:
self.handle_resizing_etc()
# need to redeclare property so it points to the right _set_file
file = property(FileField._get_file, _set_file, FileField._del_file)
免责声明:我没有在生产代码中使用过这种方法,在发布此答案之前我也没有编写概念证明,因此它可能无法按预期工作
这个问题看起来像 Programmatically saving image to Django ImageField
的重复
ImageField.save()
方法的参数为FileField.save()
(其中ImageField
是一个子类)记录:
https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.fields.files.FieldFile.save
Takes two required arguments: name which is the name of the file, and
content which is an object containing the file’s contents. The
optional save argument controls whether or not the model instance is
saved after the file associated with this field has been altered.
Defaults to True.
以下是对我们有效的方法:
class CustomImage(models.Model):
image = models.ImageField(upload_to=get_file_path, max_length=500)
orig_name = models.TextField()
这是从 http 资源向 ImageField 添加图像文件的方法:
from django.core.files.base import ContentFile
def download_photo(amazon_id, url):
img_data = requests.get(url)
img = CustomImage(orig_name=img_data.url)
img.image.save(slugify(img.orig_name), ContentFile(img_data.content), save=True)
它也可以在没有 ContentFile 的情况下工作:
new_img = File(open(different_obj.image.path), 'r')
img.image.save(different_obj.image.url, new_img, save=True)
另请参阅:
- https://docs.djangoproject.com/en/1.9/topics/files/
- https://djangosnippets.org/snippets/2587/
我有一个带有自定义图像字段的 Django 模型。图像字段在上传时创建一些缩略图大小。代码可能如下所示:
from django.db import models
from utils import CustomImageField
class Photo(models.Model):
image = CustomImageField()
现在我修改原始图像,假设我旋转了它。现在我想再次触发图像字段的保存方法,以覆盖缩略图并创建旋转版本。因此,我不需要在我的代码中的其他地方旋转缩略图 (DRY)。
有什么想法吗?符合这些思路 - 但究竟如何?
p = Photo.objects.get(pk=1)
p.image.save(...)
我可以完全控制 CustomImageField
小部件。 save()
方法定义为:
def save(self, name, path, save=True):
问题是,方法参数使用什么?
一个选项是手动检查脏字段(请参阅此 SO question) or using a pypi package
或者,如果您想节省内存,可以从字段的 属性 setter 触发调整大小(假设您继承自 FileField
class CustomImageField(FileField):
def _set_file(self, file):
has_file_changed = file != self._file
super(CustomImageField, self)._set_file(file)
if has_file_changed:
self.handle_resizing_etc()
# need to redeclare property so it points to the right _set_file
file = property(FileField._get_file, _set_file, FileField._del_file)
免责声明:我没有在生产代码中使用过这种方法,在发布此答案之前我也没有编写概念证明,因此它可能无法按预期工作
这个问题看起来像 Programmatically saving image to Django ImageField
的重复ImageField.save()
方法的参数为FileField.save()
(其中ImageField
是一个子类)记录:
https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.fields.files.FieldFile.save
Takes two required arguments: name which is the name of the file, and content which is an object containing the file’s contents. The optional save argument controls whether or not the model instance is saved after the file associated with this field has been altered. Defaults to True.
以下是对我们有效的方法:
class CustomImage(models.Model):
image = models.ImageField(upload_to=get_file_path, max_length=500)
orig_name = models.TextField()
这是从 http 资源向 ImageField 添加图像文件的方法:
from django.core.files.base import ContentFile
def download_photo(amazon_id, url):
img_data = requests.get(url)
img = CustomImage(orig_name=img_data.url)
img.image.save(slugify(img.orig_name), ContentFile(img_data.content), save=True)
它也可以在没有 ContentFile 的情况下工作:
new_img = File(open(different_obj.image.path), 'r')
img.image.save(different_obj.image.url, new_img, save=True)
另请参阅: - https://docs.djangoproject.com/en/1.9/topics/files/ - https://djangosnippets.org/snippets/2587/