How to delete old image when update ImageField?

前端 未结 8 1563
被撕碎了的回忆
被撕碎了的回忆 2020-12-13 09:20

I\'m using Django to create a stock photo site, I have an ImageField in my model, the problem is that when the user updates the image field, the original image file isn\'t d

相关标签:
8条回答
  • 2020-12-13 09:28

    Completing Chris Lawlor's answer, tried this and works.

    from YOURAPP.settings import BASE_DIR
    
    try:
        os.remove(BASE_DIR + user.userprofile.avatarURL)
    except Exception as e:
        pass 
    

    The URL has a pattern of /media/mypicture.jpg

    0 讨论(0)
  • 2020-12-13 09:29

    try this, it will work even if old file is deleted

    def logo_file(instance, filename):
    
        try:
            this = business.objects.get(id=instance.id)
            if this.logo is not None:
                path = "%s" % (this.logo)
                os.remove(path)
        finally:
            pass..
    

    code will work even without "try .. finally" but it will generate problem if file was accidently deleted. changed: move model matching inside "try" so it will not throw any error at user signup Let me know if there are any problems.

    0 讨论(0)
  • 2020-12-13 09:31

    Use this custom save method in your model:

    def save(self, *args, **kwargs):
        try:
            this = MyModelName.objects.get(id=self.id)
            if this.MyImageFieldName != self.MyImageFieldName:
                this.MyImageFieldName.delete()
        except: pass
        super(MyModelName, self).save(*args, **kwargs)
    

    It works for me on my site. This problem was bothering me as well and I didn't want to make a cleanup script instead over good bookkeeping in the first place. Let me know if there are any problems with it.

    0 讨论(0)
  • 2020-12-13 09:31

    Here is an app that deletes orphan files by default: django-smartfields. It will remove files whenever:

    • field value was replaced with a new one (either uploaded or set manually)
    • field is cleared through the form (in case that field is not required, of course)
    • the model instance itself containing the field is deleted.

    It is possible to turn that cleanup feature off using an argument: ImageField(keep_orphans=True) on per field basis, or globally in settings SMARTFIELDS_KEEP_ORPHANS = True.

    from django.db import models
    
    from smartfields import fields
    
    class MyModel(models.Model):
        image = fields.ImageField()
        document = fields.FileField()
    
    0 讨论(0)
  • 2020-12-13 09:33

    You can define pre_save reciever in models:

    @receiver(models.signals.pre_save, sender=UserAccount)
    def delete_file_on_change_extension(sender, instance, **kwargs):
        if instance.pk:
            try:
                old_avatar = UserAccount.objects.get(pk=instance.pk).avatar
            except UserAccount.DoesNotExist:
                return
            else:
                new_avatar = instance.avatar
                if old_avatar and old_avatar.url != new_avatar.url:
                    old_avatar.delete(save=False)
    

    My avatrs has unique url for each person like "avatars/ceb47779-8833-4719-8711-6f4e5cabb2b2.png". If user upload new image with different extension like jpg, delete_file_on_change_extension reciever remove old image, before save new with url "avatars/ceb47779-8833-4719-8711-6f4e5cabb2b2.jpg" (in this case). If user uploads new image with same extension django overwrite old image on storage (disk), because images paths are the same. This works fine with AWS S3 django-storage.

    0 讨论(0)
  • 2020-12-13 09:45

    Before updating the model instance, you can use the delete method of FileField object. For example, if the FileField or ImageField is named as photo and your model instance is profile, then the following will remove the file from disk

    profile.photo.delete(False)
    

    For more clarification, here is the django doc

    https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.fields.files.FieldFile.delete

    0 讨论(0)
提交回复
热议问题