Dalvtor
Dalvtor

Reputation: 3286

Django - How to get rid of multiple saves

I have the following model.

class Post(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    image = models.ImageField(max_length=255, upload_to='posts/images/', null=True, blank=True)
    thumbnail = models.FilePathField(path=settings.MEDIA_ROOT, max_length=255, null=True, blank=True)

As you can see, I need two images here, the raw image that the user uploads, and a thumbnail version that I will use on the home page.

The thing is that I am creating the thumbnail on the save method using this code:

def save(self, *args, **kwargs):
    super(Post, self).save(*args, **kwargs)
    # Get the thumbnail from the image
    if self.image:
        self.thumbnail = get_thumbnail(self.image, '500x500', crop='center', quality=85).url
    super(Post, self).save(*args, **kwargs)

I can't get rid of the first super(Post, self).save(*args, **kwargs) because I want self.image to be available, and I can't get rid of the second super(Post, self).save(*args, **kwargs) because then the thumbnail won't be saved.

I am pretty sure there must be another way of doing this.

Could you please give me a few pointers?

Upvotes: 0

Views: 38

Answers (1)

JPG
JPG

Reputation: 88589

Use update() method of QuerySet

class Post(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    image = models.ImageField(max_length=255, upload_to='posts/images/', null=True, blank=True)
    thumbnail = models.FilePathField(path=settings.MEDIA_ROOT, max_length=255, null=True, blank=True)

    def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        # Get the thumbnail from the image
        if self.image:
            thumbnail = get_thumbnail(self.image, '500x500', crop='center', quality=85).url
            Post.objects.filter(pk=self.pk).update(thumbnail=thumbnail)

Note: The update process should be inside the if... clause :)

Upvotes: 1

Related Questions