@gh0sty
Веб-разработчик. Пишу под Python Django.

Как переопределить метод save, для изменения другой модели Django?

Создаю систему рейтинга на Django.

У меня есть 3 модели - Review (отзывы), Profile (профиль) и Advert (объявления).
Модель Peview содержит integer поле stars и поле ad.
ad - форейнг ки на объект Advert, к которому прикреплен отзыв.
Модель Advert в свою очередь содержит форейн ки на объект Profile, владельца объявления.
Модель Profile содержит integer поле rating.

И я хочу при сохранении (создании или обновлении) объекта модели Review, переопределять rating в модели Profile.
Можно ли сделать такое? Есть вариант получше?
Вот мой код метода save для Review, я пока не понимаю, что делает super, поэтому он нерабочий:

def save(self, *args, **kwargs):
        super().save(*args, **kwargs) # надеюсь эта строчка сохраняет объект review
        all_ads = Advert.objects.filter(profile_id=self.ad.profile.id) # эта строчка берет все объявления пользователя (работает)
        reviews = []
        # цикл выбирает все review, на все объявления этого пользователя (работает)
        for rev in Review.objects.filter(status='active'):
            if rev.ad in all_ads:
                reviews.append(rev)
        rev_stars = 0
        for r in reviews:
            rev_stars += r.stars
        new_rating = round((rev_stars+3)/len(reviews)) # подсчет рейтинга (среднее из stars + округление + default-значение "3") (работает, вроде считает)
        self.ad.profile.rating = new_rating # внесение изменений в модель профиля, Review --> Advert --> Profile --> rating
        # super(self.ad.profile, self).save(*args, **kwargs)
        # не знаю как сохранить обновленную модель
  • Вопрос задан
  • 563 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Если ваш сервис сейчас не испытывает лютых нагрузок в сотни запросов в секунду, и вопрос об оптимизации в жёлтой зоне ещё не встал, то лучше не хранить поле rating, а добавлять аннотацией в момент выборки данных из БД. Если же СУБД надо разгрузить любой ценой, то надо не save переопределять, а обработчик сигнала pre_save объявить, в котором записывать это поле.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы