0

I have such Django models:

class Car(models.Model):
    rating = models.PositiveIntegerField(
        default=0,
        verbose_name=_('Rating'),
    )

class ReportInfo(models.Model):
    car = models.ForeignKey(
        Car,
        related_name='car_info',
        verbose_name='Report',
    )

And I need to form rating for my car instances including info from reports, in such way:

def save(self, *args, **kwargs):
    rating = 0
    for item in self.car_info.all():
        rating += 10
    self.rating = rating
    super(Car, self).save(*args, **kwargs)

So, I need to get all reports of my car, then get some other data from the report and then save rating into the field. But, self.car_info.all() returns me old data. That means next: when I click save button in admin page of a new car, my code in save method does not have access to real reports, as they are not created yet.

Do you understand? What can I do?

Q-bart
  • 1,503
  • 4
  • 22
  • 41

2 Answers2

3

Flip the order with wich ModelAdmin calls save_model() and save_related(). This way, from Model.save() you will be able to reach the updated values of the related fields, as stated in this post.

class Car(models.Model):
    ...

    def save(self, *args, **kwargs):
        if not self.id:
            super().save(*args, **kwargs)
        rating = 0
        for item in self.car_info.all():
            rating += 10
        self.rating = rating
        super(Car, self).save(*args, **kwargs)


class CarAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        if not obj.pk: 
            super().save_model(request, obj, form, change)
        else:
            pass 

    def save_related(self, request, form, formsets, change):
        form.save_m2m()
        for formset in formsets:
            self.save_formset(request, form, formset, change=change)
        super().save_model(request, form.instance, form, change)

Now, self.car_info.all() will return the updated data.

raratiru
  • 8,748
  • 4
  • 73
  • 113
2

The problem here is the order of saving in Django.

A similar question was already asked and answered.

You can simply override the save_formset for your admin site as shown in the link.

Community
  • 1
  • 1
brunostuyts
  • 654
  • 5
  • 10