【问题标题】:Django Rest Framework join 2 tables on non- foreign key fieldsDjango Rest Framework 在非外键字段上加入 2 个表
【发布时间】:2017-03-18 20:23:35
【问题描述】:

我在我的网站上使用 Django,因此决定使用 Django Rest Framework 来构建我的 REST API。但是,我在加入表格时面临一个常见问题。如果连接是在直接外键上定义的,那么一切正常。但是,当在非直接外键字段上定义连接时,事情就会变得混乱。

例如,我将玩家的统计数据存储在一张表中。 (统计表有 1 个 fk -> player) 我将比赛的参与者存储在另一张桌子上(这张桌子有 2 个 fk -> 玩家,比赛)

如果我使用播放器元数据检索统计信息,一切正常。但我想检索给定比赛中所有玩家的统计数据。

在 SQL 中,我可以将参与者表与玩家 ID 上的 stats 表连接起来(常见的 fk,但就 Django 而言,两个表之间没有直接链接,即在 2 个表的各个模型上没有定义任何内容)然后过滤竞争。

select a.* from Stats a inner join Participants b on a.player = b.player where competition = '%s'

如何使用 Django 对象语法复制它?我想将其转换为:

Stats.objects.filter(stats__competition = %s)

到目前为止,我一直使用原始 SQL 作为解决方法。但是,我想转向更永久的解决方案。

有什么建议吗?如果迁移很简单并且这个连接问题很容易解决,我愿意迁移到不同的 REST 框架(远离 Django REST)。

编辑:添加简约模型:

class Stats(models.Model):
    player = models.ForeignKey(Player, related_name='stats_player')
    ... (other fields)

class Participants(models.Model):
    player = models.ForeignKey(Player, related_name='participant_player')
    competition = models.ForeignKey(Competition, related_name='participant_competition')

【问题讨论】:

    标签: django join django-rest-framework


    【解决方案1】:

    这样的事情应该可以工作: Stats.objects.filter(player__competitions = '%s')
    (它将返回参加给定比赛的玩家的统计数据)

    我们需要您的 Django 模型声明来确定字段名称。
    以下是可以使用此过滤器的示例模型:

    class Stats(models.Model):
      player = ForeignKey(Player, related_name='stats_player')
      ...
    
    class Competition(models.Model):
       name = CharField(max_length=32)
    
    class Player(models.Model):
       competitions = ManyToManyField(Competition)
    

    那你可以写Stats.objects.filter(player__competitions__name = '%s')

    您可以选择为您的多对多关系指定参与者模型,但您不必这样做:

    class Player(models.Model):
        competitions = ManyToManyField(Competition, through='Participant')
    
    class Participant(models.Model):
        player = models.ForeignKey(Player, related_name='participant_player')
        competition = models.ForeignKey(Competition, related_name='participant_competition')
        ... other fields
    

    【讨论】:

    • 我添加了简约模型。您提出的解决方案不起作用,因为玩家模型没有竞争场...
    • 如果你使用ManyToManyField,玩家模型不需要竞争字段。通过参数,ManyToManyField 可以使用您的 Participant 表。见docs.djangoproject.com/en/1.10/ref/models/fields/…
    • nice.. 我认为您修改后的答案应该可以工作.. 但我目前陷入循环导入问题.. (感谢将我的模型拆分为各种文件以获得所需的架构名称!)
    • 所以我会试试你的建议并回复你!因为周期性进口问题被证明是非常麻烦的解决..
    • 你也可以使用字符串来定义你的ForeignKeys:ForeignKey(Player)可以写成ForeignKey('Player')(这样你就不需要导入Player模型了)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    相关资源
    最近更新 更多