我有这个将多个表连接在一起的查询:
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
不是任何表中的外键,我将如何进行第三次连接?谢谢!
答案 0 :(得分:0)
select_related(*fields)返回一个“跟随”外键关系的QuerySet,[...]
根据django文档select_related
遵循外键关系。 player_data
是一个外键,甚至是Stats
的字段。如果您想要 INNER加入 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加入(顺便说一句,如果不使用raw:Django Custom Left Outer Join也不是那么容易)也可以使用。
有关模特的快速说明:
.id
或.pk
访问。因此,无需添加例如player_id
models.ForeignKey
字段引用一个对象,而不是它的id。因此,将player_id
重命名为player
更为直观。如果您为自己的字段命名player
,则django允许您通过player_id