Django select_related 反向
Posted
技术标签:
【中文标题】Django select_related 反向【英文标题】:Django select_related in reverse 【发布时间】:2016-10-05 18:31:00 【问题描述】:我有以下型号:
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
的东西,但反过来呢?一种进行大型查询以获取所有广告系列以及相关头寸和交易的方法,而无需逐个循环。
【问题讨论】:
prefetch_related
怎么样?它会单独查找并更新 python 中多对一和多对多关系的实例。
prefetch_related 并通过 .values() 和 .values_list() 仅获取需要的字段
太好了,谢谢。我知道 prefetch_related 但并不真正了解它的用途。到现在为止。
【参考方案1】:
感谢 cmets 中的建议,我最终得到了以下可行的解决方案:
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
【讨论】:
您是如何设法访问 cached_positions 的? 这可能是关于该主题的唯一问题和答案!很好的解决方案,谢谢。我一直在寻找类似的东西。我有一组类似的关系,我一直在为 WRT 序列化而苦苦挣扎。以上是关于Django select_related 反向的主要内容,如果未能解决你的问题,请参考以下文章
django: select_related() 在一个已经存在的对象上?
如何使用'select_related'从相关(ForeignKey)django模型中接收并非所有字段