优化Django反向查询

js4nwp54  于 2023-03-09  发布在  Go
关注(0)|答案(1)|浏览(111)

我有2个模特

class Chassis(models.Model):
    number = models.CharField(max_length=10, unique=True)

class Eir(models.Model):
    chassis = models.ForeignKey(
        'management.Chassis',
        null=True,
        blank=True,
        related_name='eir',
        on_delete=models.SET_NULL
    )
    number = models.IntegerField(unique=True, default=0)

我通过Django CLI测试

>>> chassis = Chassis.objects.prefetch_related('eir')
>>> chassis
>>> chassis.first().eir.all()

我尝试了上面的命令,它仍然使用eir表进行查询,如下所示:

# produced from ">>> chassis"
{"Time":[2023-03-07 08:25:42 UTC], Host:10.116.1.165} LOG:  duration: 0.238 ms  statement: SELECT "management_chassis"."id", "management_chassis"."number" FROM "management_chassis" LIMIT 21
{"Time":[2023-03-07 08:25:42 UTC], Host:10.116.1.165} LOG:  duration: 0.777 ms  statement: SELECT "rental_eir"."id", "rental_eir"."number", "rental_eir"."chassis_id" FROM "rental_eir" WHERE "rental_eir"."chassis_id" IN (1292, 104)

# produced from ">>> chassis.first().eir.all()"
{"Time":[2023-03-07 08:25:59 UTC], Host:10.116.1.165} LOG:  duration: 0.239 ms  statement: SELECT "rental_eir"."id", "rental_eir"."number", "rental_eir"."chassis_id" FROM "rental_eir" WHERE "rental_eir"."chassis_id" IN (1292)

我希望不再有第三次查询,因为数据将被存储在内存中。我的真实的目的是与Django REST框架有关,在def to_representation中操作返回的数据,其中反向查找类似于ret['eir'] = instance.eir.all().last().id,其中instanceChassis模型。
一般来说,我试图减少不必要的查询产生。

x4shl7ld

x4shl7ld1#

.first()不读取该高速缓存。
如果你想减少查询的数量,你需要把查询集转换成列表。
但是,如果您不需要整个“chassis”列表,chassis.first().eir.all()会导致更精简的查询(tank到limit 1)。

>>> chassis = list(Chassis.objects.prefetch_related('eir'))
>>> chassis
>>> chassis[0].eir.all()

然而,这与您描述的序列化器的用例相比有点不同。
如果“eir”为预取,则将ret['eir'] = instance.eir.all().last().id替换为ret['eir'] = instance.eir.all()[-1].id应生成最少的查询

相关问题