Django将id从实例传递到未实例化的模型字段



在我的ProductImages模型中,我制作了一些字段来存储各种类型的同一图像,如:

型号.py

class ProductImages(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
#This field is used in form    
image_file_w200_png = models.ImageField(

verbose_name = "Selecione a imagem",
upload_to=upload_to_image_file_w200_png,
null=True,
blank=True,
default='magickhat-profile.jpg'
)
#This field is not used in forms
image_file_w480_png = models.ImageField(
upload_to=upload_to_image_file_w480_png,
null=True,
blank=True,
default='magickhat-profile.jpg'
)
...
def save(self, *args, **kwargs):
try:
this = ProductImages.objects.get(id=self.id)
if this.image_file_w200_png != self.image_file_w200_png:
this.image_file_w200_png.delete(save=False)
if this.image_file_w480_png != self.image_file_w480_png:
this.image_file_w480_png.delete(save=False)
except:
pass

# resize function on utils.py
image_manipulation(self)
if self.id is None:
saved_image_w200_png = self.image_file_w200_png
self.image_file_w200_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w200_png = saved_image_w200_png
saved_image_w480_png = self.image_file_w480_png
self.image_file_w480_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w480_png = saved_image_w480_png
if 'force_insert' in kwargs:
kwargs.pop('force_insert')
super(ProductImages, self).save(*args, **kwargs)

好吧,想法是当用户从image_file_w200_png字段上传图像时,图像被调整为各种尺寸,我将其他图像保存在其他字段中,如image_file_w480_png

我的实际问题出现在upload_to中,正如我们在文档upload_to may also be a callable, such as a function中看到的那样。因此,我在utils.pyupload_to中为每个字段创建了自己的函数。

utils.py-请检查评论

# Here instance.id have value
def upload_to_image_file_w200_png(instance, filename):
ext = filename.split('.')[-1]
filename = instance.product.slug+"_"+str(instance.id)+"_w200_png."+ext
return 'user_{0}/{1}/{2}/{3}'.format(instance.product.user.id, instance.product.id, instance.id,  filename)
"""
Here instance(ProductImages) is not initialized,value is none
For example in php i just store $_SESSION['id'] = instance.id in above function and call this session here, idk how python do equivalent, not even if that is the right approach
""" 
def upload_to_image_file_w480_png(instance, filename):
ext = filename.split('.')[-1]
filename = instance.product.slug+"_"+str(instance.id)+"_w480_png."+ext
return 'user_{0}/{1}/{2}/{3}'.format(instance.product.user.id, instance.product.id, instance.id,  filename)
def image_manipulation(self):
image_original = self.image_file_w200_png

#image_resize_w200 to png
image_open_w200_png = Image.open(image_original)
image_output_w200_png = BytesIO()
image_resize_w200_png = image_open_w200_png.resize((200,300))
image_resize_w200_png.save(image_output_w200_png, format="PNG", optimize=False, quality=10)
image_output_w200_png.seek(0)
self.image_file_w200_png = InMemoryUploadedFile(image_output_w200_png,'ImageField',"%s.png" %self.image_file_w200_png.name.split('.')[0],'image/png',sys.getsizeof(image_output_w200_png), None)

#resize image small width 480 to png
image_open_w480_png = Image.open(image_original)
image_output_w480_png = BytesIO()
image_basewidth_w480_png = 480
image_wpercent_w480_png = (image_basewidth_w480_png / float(image_open_w480_png.size[0]))
image_hsize_w480_png = int((float(image_open_w480_png.size[1]) * float(image_wpercent_w480_png)))
image_resize_w480_png = image_open_w480_png.resize((image_basewidth_w480_png,image_hsize_w480_png), Image.LANCZOS)
image_resize_w480_png.save(image_output_w480_png, format="PNG", optimize=True, quality=10)
image_output_w480_png.seek(0)
self.image_file_w480_png = InMemoryUploadedFile(image_output_w480_png,'ImageField',"%s.png" %self.image_file_w480_png.name.split('.')[0],'image/png',sys.getsizeof(image_output_w480_png), None)

问题是,instance.id是场图像的id,但唯一实例化的场是image_file_w200_png场,而image_file_w480_png不是,那么我如何在upload_to_image_file_w480_png函数中使用upload_to_image_file_w200_png函数中的instance.id呢?

调用super(ProductImages, self).save(*args, **kwargs)时,会为两个ImageField调用

upload_to

self.image_file_w480_png = None设置在super(ProductImages, self).save(*args, **kwargs)之前。

if self.id is None:
# saved_image_w200_png = self.image_file_w200_png
# self.image_file_w200_png = None
# super(ProductImages, self).save(*args, **kwargs)
# self.image_file_w200_png = saved_image_w200_png
# saved_image_w480_png = self.image_file_w480_png
# self.image_file_w480_png = None
# super(ProductImages, self).save(*args, **kwargs)
# self.image_file_w480_png = saved_image_w480_png
saved_image_w200_png = self.image_file_w200_png
saved_image_w480_png = self.image_file_w480_png
self.image_file_w200_png = None
self.image_file_w480_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w200_png = saved_image_w200_png
self.image_file_w480_png = saved_image_w480_png

最新更新