如何避免重复django预取相关的数据库命中

时间:2018-04-20 16:03:33

标签: django django-models prefetch django-1.11 django-managers

当我获取客户端时,我还想预取所有相关的探测和探测通道,当我获取探测时,我也想获取所有相关的探测通道。

但似乎当我获得客户端对象或查看管理员时,它会从客户端和探针管理器运行get_queryset方法。所以它会预取两次探测通道。这可以在调试工具栏中的sql查询数量以及在get_queryset方法中添加print语句中看到。 所以我有

class ClientManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        return super(ClientManager, self).get_queryset(*args, **kwargs).prefetch_related('probe_set__probechannel_set')

class Client(models.Model):
    objects = ClientManager()

class ProbeManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        return super(ProbeManager, self).get_queryset(*args, **kwargs).prefetch_related('probechannel_set')

class Probe(models.Model):
    Client = models.ForeignKey('Client')
    objects = ProbeManager()

class ProbeChannel(models.Model):
    Probe = models.ForeignKey('Probe')

有没有办法避免这种情况?我已经阅读了有关_base_managers用于相关对象的内容,但这里的_base_manager只是models.Manager。我正在使用django 1.11和这个时髦的新东西叫做python 2.7。

1 个答案:

答案 0 :(得分:0)

我仍然不确定这是否需要Django行为,但预取肯定会发射两次。我已经解决了以避免ProbeManager预取被解雇的答案很简单 - 避免使用这个管理器。 所以在Probe课程中我添加了

objects_without_prefetch = models.Manager()

然后使用预取对象Prefetch(' probe_set',Probe.objects_without_prefetch.all())而不是简单地使用' probe_set'它正在调用自己的预取。

非常感谢那些花时间思考并回答的人!