避免通过其他多对多关系对自己进行多对多关系的n + 1查询

时间:2018-09-26 10:42:39

标签: django django-models prefetch

我有一个PolygonMap的模型,它由多个PolygonTiles组成。每个PolygonTile都有一个中心点和由CornerPoints跨越的多个Edges

因此,每个Edge具有两个CornerPoints和两个PolygonTiles。可以通过下面介绍的模型Edge上的两个多对多关系来实现,并且可以正常工作(将PostgreSQL用于distinct()的自变量字段)。

class PolygonMap(models.Model):
  pass

class PolygonTile(models.Model):
  location = PointField()
  polygon_map = models.ForeignKey(PolygonMap, on_delete=models.CASCADE)

  def adjacent(self):
    return PolygonTile.objects.filter(edges__polygon_tiles=self).exclude(id=self.id)

  def corner_points(self):
    return CornerPoint.objects.filter(protruded_edges__polygon_tiles=self).distinct('id')

class CornerPoint(models.Model):
  location = PointField()
  polygon_map = models.ForeignKey(PolygonMap, on_delete=models.CASCADE)      
  # ... functions like the ones in PolygonTiles

class Edge(self):
  polygon_tiles = models.ManyToManyField(PolygonTile, related_name='edges')
  corner_points = models.ManyToManyField(CornerPoint, related_name='protruded_edges')

对于PolygonTile中的每个PolygonMap,我现在要获取所有相邻的PolygonTiles(稍后再访问CornerPoints)。我可以使用

polygon_tiles = PolygonMap.objects.first().polygontile_set.all()
adjacent = [p.adjacent() for p in polygon_tiles]

您可以想象这将导致对相邻PolygonTiles的N + 1个查询。

所以我的问题是,如何解决这个问题?我曾尝试使用prefetch_related有无Prefetch对象,自定义管理器和重写邻接查询的组合,但似乎无法正常工作。

0 个答案:

没有答案