Запрос на удаление альбома в приложении Django

Суть кейса: Есть картинки(сущность в бд). Также есть альбомы, которые могут содержать картинки. По факту картинка может быть : либо в одном альбоме, либо в нескольких, либо ни в одном(связь mtm проще говоря). Когда приходит запрос на удаление альбома, нужно проверить, есть ли в нем картинка, которая содержится в других альбома. Если картинка находится только в данном альбоме - удаляем альбом и картинку. Если нет - картинку оставляем. Код:

#album.models
class AlbumManager(Manager):

    # def annotate_count_pictures(self, queryset):
    #     queryset.prefetch_related('album_pictures')

    def get_pictures(self, id=None):
        queryset = AlbumPicture.objects.select_related('picture').values('picture_id').annotate(count=Count('picture_id'))
        return queryset.all()


# Create your models here.
class Album(models.Model):
    name = models.CharField(max_length=200, blank=False, null=False)
    user = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE)
    date_created = models.DateTimeField(default=datetime.now())

    objects = AlbumManager()

    class Meta:
        db_table = 'album'

    def delete(self, using=None, keep_parents=False):
        return super().delete(using, keep_parents)


class AlbumPicture(models.Model):
    picture = models.ForeignKey('picture.Picture', related_name='picture_album', blank=False, null=True,
                                on_delete=models.CASCADE)
    album = models.ForeignKey(Album, related_name='album_picture', blank=False, null=True, on_delete=models.CASCADE)

    class Meta:
        db_table = 'album_picture'


#picture.models
class Picture(models.Model):
    name = models.CharField(max_length=255, blank=False)
    user = models.ForeignKey(User,  related_name='user_picture', null=False, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='media')
    date_of_published = models.DateTimeField(blank=False, default=datetime.now())
    likes = models.PositiveIntegerField(null=False, blank=False, default=0)
    album = models.ManyToManyField(Album, through=AlbumPicture, related_name='album_pictures', blank=True)
    category = models.ForeignKey('PictureCategory', blank=False, null=False, on_delete=models.DO_NOTHING)

    objects = PictureManager()

    def get_absolute_url(self):
        return reverse('retrieve-update-destroy-picture', kwargs={'id': self.id})

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['date_of_published']
        db_table = 'picture'

Код сервиса(вызывается в хуке perform_destroy -> instance - это обьект модели Album):

def delete_album_with_images(instance):
    pictures = Album.objects.get_pictures(instance.id)
    picture_to_delete_ids = []
    for p in pictures:
        if p.get('count') == 1:
            picture_id = p.get('picture_id')
            picture_to_delete_ids.append(picture_id)
    Picture.objects.filter(id__in=picture_to_delete_ids).delete()
    instance.delete()

Я пытался писать запросы с group by(используя values), однако там возвращаются обьекты ввиде словаря, так что потом приходится делать еще один запрос на каждую картинку. Какие есть идеи по поводу оптимизации данного запроса?

Вернуться на верх