如何使用带有WHERE子句的Django ORM连接三个表

时间:2017-09-20 08:29:20

标签: django django-models django-orm

我有三种模式:

class model_A(models.Model):
    data_1 = models.CharField(max_length=60)
    data_2 = models.SmallIntegerField()
    data_3 = models.IntegerField(blank=True, null=True)

class model_B(models.Model):
    data_a = models.ForeignKey(model_A)
    data_1 = models.CharField(max_length=5)
    data_2 = models.IntegerField()

class model_C(models.Model):
    data_a = models.ForeignKey(model_A)
    data_1 = models.CharField(max_length=5)
    data_2 = models.IntegerField()

因此您可以看到model_B → model_Amodel_C → model_A之间存在一对一的关系,这很简单。

我需要使用WHERE子句对这三个表进行JOIN,因此对于RAW SQL,它将是:

SELECT * FROM `model_A` JOIN `model_B` ON `model_A`.`data_1` = `model_B`.`data_a` JOIN `model_C` ON `model_A`.`data_1` = `model_C`.`data_a` WHERE `model_B`.`data_1` = 1 AND `model_C`.`data_1` = 1

如何使用Django ORM连接这三个表(使用filter语句(WHERE子句))?

可能重复吗? 有人链接的重复问题已与TWO表连接,使用select_related()很容易解决。但它有三个表不起作用(或者我不知道如何在这种情况下使用它)。

2 个答案:

答案 0 :(得分:1)

试试这个

query_set = model_A.objects.filter(modelb__data_1=1, modelc__data_1=1)

对于模型B数据

query_set = model_B.objects.filter(data_1=1, data_a__modelc__data_1=1)

希望这有助于你

答案 1 :(得分:1)

当然,这并不是一个好的模型定义,所以让我们先解决这个问题:

from django.db import models

class Artist(models.Model):
    name = models.CharField(max_length=60)
    year_established = models.SmallIntegerField()
    votes = models.IntegerField(blank=True, null=True)


class Song(models.Model):
    artist = models.ForeignKey(Artist, related_name='songs')
    title = models.CharField(max_length=5)
    votes = models.IntegerField()


class Fan(models.Model):
    artist = models.ForeignKey(Artist, related_name='fans')
    name = models.CharField(max_length=5)
    votes_casted = models.IntegerField()

现在让我们为所有写过爱情歌曲的艺术家和拥有至少100票的粉丝:

queryset = Artist.objects.select_related(
    'songs', 'fans'
).filter(songs__title__icontains='love', fans__votes_casted__gte=100)

请注意,select_related在查询中不起作用:它是在迭代集合时最小化查询的优化。

进一步阅读:

编辑:添加了select_related。理论上这应该可以起作用并减少查询,但是如果它没有,我明天就会查看它。