Django FileField在上传后移动文件

时间:2016-07-14 10:51:37

标签: python django django-models

围绕这个主题有几个问题,但我找不到适合我试图做的事情。我希望能够将文件上传到模型,并使用像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.pathimage.name,{{image.url 1}}等等?

docs说上面的内容是我应该做的,但这只会导致image字段指向一个不存在的文件。我查看了this相关问题并尝试了其中一个答案中提到的snippet,但我还没有找到解决方案。

1 个答案:

答案 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它看起来很明显:)但我确实认为解释可以更具描述性。希望这会节省一些时间!