[Django]-Django get rid of duplicated queries in nested models

3👍

If you use .prefetch_related it will populate the carvariant_set value, but only for a .all() query, not for a .last(), that will trigger a new query.

What we can do is define a property like:

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    name = models.CharField(max_length=300)
    
    @property
    def latest_variant(self):
        items = getattr(self, '_latest_variants', ())
        if items:
            return items[-1]
        return self.carvariant_set.last()

Then we can prefetch the related object with:

from django.db.models import Prefetch

Car.objects.prefetch_related(
    Prefetch(
        'carvariant_set',
        queryset=CarVariant.objects.order_by('pk'),
        to_attr='_latest_variants'
    )
)

0👍

To get rid of duplicates you use "distinct()".
For example Car.objects.all().prefetch_related(‘carvariant_set’).distinct(). You can read about it here:
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.distinct

sometimes you might need to tell the "distinct" function which fields make an object distinct. By default it’s the id, but you can do something like "distinct(‘name’)" in order to avoid getting 2 instances with the same name for example.

👤yo1122

Leave a comment