Django select_related反向

时间:2016-06-06 08:13:48

标签: python django django-orm

我有以下型号:

class Campaign(models.Model):
    some_campaign_field = models.CharField()

class Position(models.Model):
    campaign = models.ForeignKey(Campaign)
    some_position_field = models.CharField()

class Trade(models.Model):
    position = models.ForeignKey(Position)
    some_trade_field = models.CharField()

换句话说,我的广告系列可以有多个职位。反过来,广告系列中的每个位置都可以有多个交易。

是否有一种有效的方式(即:最小的数据库调用)来选择一个广告系列及其所有相关的头寸和交易。它看起来不像我可以使用select_related,因为它只能用于其他方式,例如:对于特定的交易,select_related将获得所有相关的头寸。

目前我在嵌套循环中执行此操作,如下所示:

campaigns = Campaign.objects.get()
for campaign in campaigns:
    positions = campaign.position_set.all()
    for position in positions:
        trades = position.trade_set.all()
        # do stuff

这可以正常工作,但就数据库被击中的次数而言效率非常低。我有更好的方法吗?有点像select_related但是相反的东西?一种方法,可以执行一个大型查询,以获取所有广告系列以及相关的“排名”和“交易”,而无需单独循环显示每个广告系列。

1 个答案:

答案 0 :(得分:3)

感谢评论中的建议,我最终得到了以下工作解决方案:

open_campaigns = list(Campaign.objects.prefetch_related(
                                       Prefetch('position_set',
                                                queryset=Position.objects.all(),
                                                to_attr='cached_positions'),
                                       Prefetch('cached_positions__trade_set',
                                                to_attr='cached_trades'),
                                       ).filter(exit_datetime__isnull=True))

修改:应添加此导入

from django.db.models import Prefetch

参考。 Prefetch docs