我有如下模型,
class Manufacturer(models.Model):
name = models.CharField(max_length=100)
class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
name = models.CharField(max_length=300)
@property
def latest_variant(self):
return self.carvariant_set.last()
class CarVariant(models.Model):
car = models.ForeignKey(Car, on_delete=models.CASCADE)
name = models.CharField(max_length=300)
,我正在查询所有汽车的最新版本,我得到了很多重复的查询。我不能用prefetch_related
Car.objects.all().prefetch_related('carvariant_set')
如何消除重复查询?
如果您使用.prefetch_related
,它将填充carvariant_set
值,但仅用于.all()
查询,而不是用于.last()
,这将触发新的查询。
我们可以定义一个属性:
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:
returnitems[-1]
return self.carvariant_set.last()
则可以使用:
预取相关对象。from django.db.models importPrefetch
Car.objects.prefetch_related(
Prefetch(
'carvariant_set',
queryset=CarVariant.objects.order_by('pk'),
to_attr='_latest_variants'
)
)
要去掉重复项,可以使用"distinct()"。例如Car.objects.all().prefetch_related('carvariant_set').distinct()。你可以在这里读到:https://docs.djangoproject.com/en/3.2/ref/models/querysets/django.db.models.query.QuerySet.distinct
有时你可能需要告诉"区别"。函数,其字段使对象不同。默认情况下,它是id,但你可以这样做:"distinct('name')"为了避免获得两个具有相同名称的实例,例如: