使用os.unlink()时,ImageField不会删除文件

时间:2011-05-01 16:24:55

标签: python django image delete-file imagefield

我有这个型号:

class UserProfile(models.Model):
    """(UserProfile description)"""
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=upload_to)

    def save(self):
        os.unlink(self.image.path)
        super(UserProfile, self).save()

脚本在unlink()方法上失败,并说无法找到该文件。有什么想法吗?

错误说

  

(2,'没有这样的文件或目录')

1 个答案:

答案 0 :(得分:2)

您需要更具体的调试。此外,您编写代码的方式可能会确保错误发生。我不完全确定,但如果在创建UserProfile记录之前未设置UserProfile.image的值,我不会感到惊讶。

所以我会这样重写你的代码:

class UserProfile(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=upload_to)

    def save(self):
        if self.image.path:
            try:
                os.unlink(self.image.path)
            except Exception, inst:
                raise Exception("Unable to delete %s. Error: %s" % (self.image.path, inst))
        super(UserProfile, self).save()

更新

现在我想起来,一旦你打电话保存,新的信息已经在self.image中了。如果您的目标是在保存新图像时删除旧图像,则需要使用pre_save signal in Django检索旧记录(以及旧图像路径)之前以保存图片。理论上,你可以将它放在save模型的UserProfile方法中,但是因为它的目的是作为不直接影响当前<的副作用/ strong>记录,我将它分开。

以下是一个示例实现:

from django.db.models import signals
def delete_old_image(sender, instance, using=None):
    try:
        old_record = sender.objects.get(pk=instance.pk)
        os.unlink(old_record.image.path)
    except sender.DoesNotExist:
        pass
signals.pre_save.connect(delete_old_image, sender=UserProfile)

您可以将其放在models.py文件中。