围绕这个主题有几个问题,但我找不到适合我试图做的事情。我希望能够将文件上传到模型,并使用像pk这样的模型实例属性将该文件保存在一个不错的位置。我知道这些东西在model.save()
后被设置好所以我需要编写一个自定义保存来执行此操作,但我无法弄明白。这就是我所拥有的:
class UploadModel(models.Model):
image = models.ImageField(upload_to='uploads')
def save(self, *args, **kwargs):
# Call standard save
super(UploadModel, self).save(*args, **kwargs)
if 'uploads' in self.image.path:
initial_path = self.image.path
# New path in the form eg '/images/uploadmodel/1/image.jpg'
new_path = os.path.join(settings.MEDIA_ROOT, 'images',
self._meta.model_name, self.pk, os.path.basename(initial_path))
# Create dir if necessary and move file
if not os.path.exists(os.path.dirname(new_path)):
makedirs(os.path.dirname(new_path))
os.rename(initial_path, new_path)
# Do something here to save the new file to the image field
# Save changes
super(UploadModel, self).save(*args, **kwargs)
我需要对image
字段做些什么才能让它引用此新文件位置,并将所有有用的属性设置为image.path
,image.name
,{{image.url
1}}等等?
docs说上面的内容是我应该做的,但这只会导致image
字段指向一个不存在的文件。我查看了this相关问题并尝试了其中一个答案中提到的snippet,但我还没有找到解决方案。
答案 0 :(得分:2)
经过大量的搜索并找到了this旧的文档票据,我发现了很好的解释。
class UploadModel(models.Model):
image = models.ImageField(upload_to='uploads')
def save(self, *args, **kwargs):
# Call standard save
super(UploadModel, self).save(*args, **kwargs)
if 'uploads' in self.image.path:
initial_path = self.image.path
# New path in the form eg '/images/uploadmodel/1/image.jpg'
new_name = '/'.join(['images', self._meta.model_name, str(self.id),
path.basename(initial_path)])
new_path = os.path.join(settings.MEDIA_ROOT, 'images',
self._meta.model_name, self.pk, os.path.basename(initial_path))
# Create dir if necessary and move file
if not os.path.exists(os.path.dirname(new_path)):
makedirs(os.path.dirname(new_path))
os.rename(initial_path, new_path)
# Update the image_file field
self.image_file.name = new_name
# Save changes
super(UploadModel, self).save(*args, **kwargs)
现在我读了docs for this它看起来很明显:)但我确实认为解释可以更具描述性。希望这会节省一些时间!