我如何将这些多个连接作为Django查询集来执行呢?
问题描述
我有一个将多个表联接在一起的查询:
select
p.player_id
, d.player_data_1
, l.year
, l.league
, s.stat_1
, l.stat_1_league_average
from
stats s
inner join players p on p.player_id = s.player_id
left join player_data d on d.other_player_id = p.other_player_id
left join league_averages as l on l.year = s.year and l.league = s.year
where
p.player_id = 123
我的模型如下所示:
class Stats(models.Model):
player_id = models.ForeignKey(Player)
stat_1 = models.IntegerField()
year = models.IntegerField()
league = models.IntegerField()
class Player(models.Model):
player_id = models.IntegerField(primary_key=True)
other_player_id = models.ForeignKey(PlayerData)
class PlayerData(models.Model):
other_player_id = models.IntegerField(primary_key=True)
player_data_1 = models.TextField()
class LeagueAverages(models.Model):
year = models.IntegerField()
league = models.IntegerField()
stat_1_league_average = models.DecimalField()
我可以这样做:
Stats.objects.filter(player_id=123).select_related('player')
执行第一个联接。对于第二个连接,我尝试:
Stats.objects.filter(player_id=123).select_related('player').select_related('player_data')
但我收到此错误:
django.core.exceptions.FieldError:SELECT_Related:‘Player_Data’中给出的字段名无效。选项包括:播放器
考虑到year
和league
在任何表中都不是外键,我该如何进行第三个连接呢?谢谢!
解决方案
select_related(*fields)返回将"遵循"外键关系的QuerySet,[.]
根据Django文档select_related
遵循外键关系。player_data
与外键相邻,甚至也不是Stats
的字段。如果您想要内部联接PlayerData
和Player
,可以跟随它的外键。在您的情况下,请使用
double-underscore转到PlayerData
:
Stats.objects.all()
.select_related('player_id')
.select_related('player_id__other_player_id')
至于联接LeagueAverages
:没有合适的外键就无法联接模型,只能使用原始SQL。看一下相关的问题:Django JOIN query without foreign key。通过使用.raw()
,您的LEFT JOIN(顺便说一句,如果不使用RAW:Django Custom Left Outer Join也不是那么容易),您的LEFT JOIN也可以得到处理。
有关您的型号的快速说明:
- 每个模型默认都有一个自动递增的主键,可以通过
.id
或.pk
访问。因此不需要添加例如player_id
models.ForeignKey
字段引用的是对象,而不是它的id。因此,例如将player_id
重命名为player
会更直观。如果您将字段命名为player
,player
Django允许您通过player_id
自动访问其ID
相关文章