Di *_*Zou 1 python django django-models django-queryset python-3.x
我有一个将多个表连接在一起的查询:
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
Run Code Online (Sandbox Code Playgroud)
我的模型看起来像这样:
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()
Run Code Online (Sandbox Code Playgroud)
我可以做这样的事情:
Stats.objects.filter(player_id=123).select_related('player')
Run Code Online (Sandbox Code Playgroud)
做第一次加入。对于第二次加入,我尝试了:
Stats.objects.filter(player_id=123).select_related('player').select_related('player_data')
Run Code Online (Sandbox Code Playgroud)
但我得到了这个错误:
django.core.exceptions.FieldError:select_lated 中给出的字段名称无效:“player_data”。选项有: 玩家
year考虑到这一点并且league任何表中都没有外键,我将如何进行第三次连接?谢谢!
\n\n\nselect_lated(*fields)返回一个 QuerySet,它将 \xe2\x80\x9cfollow\xe2\x80\x9d 外键关系,[...]
\n
根据 django 文档, select_related遵循外键关系。player_data既不是外键,也不是 的字段Stats。如果你想要INNER join PlayerData,Player你可以遵循它的外键。在您的情况下,使用 \n双下划线来访问PlayerData:
Stats.objects.all()\n .select_related(\'player_id\')\n .select_related(\'player_id__other_player_id\')\nRun Code Online (Sandbox Code Playgroud)\n\n至于连接LeagueAverages:没有适当的外键来连接模型,而是使用原始sql。看一下相关问题:Django JOIN query withoutforeign key。通过使用.raw(),您的LEFT 连接(顺便说一下,如果不使用 raw:Django Custom Left Outer Join也不是那么容易)也可以得到处理。
关于您的模型的快速说明:
\n\n.id或访问.pk。所以不需要添加例如player_idmodels.ForeignKey引用一个对象而不是它的 id。因此,重命名为更player_id直观player。如果你命名你的字段,playerdjango 允许你通过以下方式自动访问它的 idplayer_id| 归档时间: |
|
| 查看次数: |
12674 次 |
| 最近记录: |