【问题标题】:How to create multiple inner joins using Django ORM?如何使用 Django ORM 创建多个内部连接?
【发布时间】:2018-06-28 04:44:31
【问题描述】:

我正在努力寻找解决以下困境的文档和示例。我有两张表,Results(包含比赛结果)和 Photos(每张照片都包含该比赛中的跑步者)。两个表都包含 entrant_numbers,即比赛中的参赛者编号和照片中的参赛者编号。在 SQL 中,我像这样加入他们以获得每个跑步者的照片捕获总数。

SELECT * FROM Photo p 
INNER JOIN Result r ON p.entrant_number=r.entrant_number AND p.race_year=r.race_year
WHERE r.user_id=123

我的模型的结构是这样的;

class Photo(models.Model):
    photo_id = models.AutoField(primary_key=True)
    race_id = models.ForeignKey('Race')
    url_pre_string = models.CharField("URL pre-string", max_length=255)
    filename = models.CharField("Filename", max_length=100)
    extension = models.CharField("File extensions", max_length=4)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)


class Race(models.Model):
    race_id = models.AutoField(primary_key=True)
    race_year = models.PositiveIntegerField("Race year", null=False, blank=False)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)


class Result(models.Model):
    result_id = models.AutoField(primary_key=True)
    race_id = models.ForeignKey('Race')
    position = models.PositiveIntegerField("Position", default=0)
    entrant_number = models.PositiveIntegerField("Entrant number", default=0, null=True, blank=True)
    user_id = models.ForeignKey(User, null=True)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

我最近尝试的查询是;

photo_captures = Photo.objects.filter(result__user_id_id=current_user.id)

我希望这会遍历结果并过滤当前用户 ID。

【问题讨论】:

  • 据我了解,每个跑者都是User,他们可以参加多场比赛。在每场比赛中,他们都有一个不同的entrant_number,这是该比赛独有的,您要做的就是从特定比赛中获取用户的所有Photo。对吗?
  • 实际上我需要所有比赛的所有照片。表格需要通过 entrant_number 和 race_year 链接,以使该用户的照片独一无二,因为用户每年可以有不同的比赛编号(因此有多个连接)。

标签: django orm inner-join


【解决方案1】:

您可以通过执行原始 SQL 查询来连接两个表。

你可以检查如何做到这一点here

from django.db import connection
def my_custom_sql(self):
    cursor = connection.cursor()    
    cursor.execute("select *
                from myapp_photo p
                inner join myapp_result r ON 
                p.entrant_number=r.entrant_number AND 
                p.race_year=r.race_year
                WHERE r.user_id=123")
    row = cursor.fetchone()
    return row

替代方式: 您可以将照片模型中的外键设置为结果模型,然后您将拥有不同结果的唯一照片。像这样:

class Result(models.Model):
    results_id = models.AutoField(primary_key=True)
    position = models.PositiveIntegerField("Position", default=0)
    entrant_number = models.PositiveIntegerField("Entrant number", default=0, null=True, blank=True)
    race_year = models.PositiveIntegerField("Race year", default=0)
    user_id = models.ForeignKey(User, null=True)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

class Photo(models.Model):
    result= models.ForeignKey(Result)
    photo_id = models.AutoField(primary_key=True)
    url_pre_string = models.CharField("URL pre-string", max_length=255)
    filename = models.CharField("Filename", max_length=100)
    extension = models.CharField("File extensions", max_length=4)
    entrant_number = models.PositiveIntegerField("Entrant number", default=0, null=True, blank=True)
    race_year = models.PositiveIntegerField("Race year", default=0)
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

然后为单个用户获取特定年度结果的照片,您可以这样做

photos = Photo.objects.filter(entrant_number = result__entrant_number,
                              race_year = result__race_year,
                              result__user_id = 123)

当然我还没有测试过,但这应该可以解决问题。让我知道这是否有效或您需要任何帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-14
    • 2020-07-27
    • 2014-02-16
    • 1970-01-01
    • 2015-04-26
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多