G
G
gh0sty2019-09-22 16:16:54
Django
gh0sty, 2019-09-22 16:16:54

How to override the save method to change another Django model?

I'm building a rating system in Django.
I have 3 models - Review (reviews), Profile (profile) and Advert (ads).
The Peview model contains an integer stars field and an ad field.
ad - forwarding key to the Advert object to which the review is attached.
The Advert model, in turn, contains a foreign key to the Profile object, the owner of the ad.
The Profile model contains an integer rating field.
And I want to override the rating in the Profile model when saving (creating or updating) the Review model object.
Is it possible to do this? Is there a better option?
Here is my save method code for Review, I don't understand what super does yet, so it's not working:

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)
        # не знаю как сохранить обновленную модель

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2019-09-22
@gh0sty

If your service is not currently experiencing heavy loads of hundreds of requests per second, and the question of optimizing in the yellow zone has not yet arisen, then it is better not to store the field rating, but to add it as an annotation at the time of fetching data from the database. If the DBMS needs to be unloaded at any cost, then it is necessary not to saveredefine, but to declare the signal handler pre_save in which to write this field.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question