如何使用带有 WHERE 子句的 Django ORM 连接三个表
How to JOIN three tables with Django ORM with WHERE clause
我有三个模型:
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_A
和 model_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 子句))?
可能重复?
有人链接的重复问题已加入两个表,使用 select_related() 很容易解决。但是它对三个表不起作用(或者我不知道在这种情况下如何使用它)。
试试这个
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)
希望对您有所帮助
当然,这不是一个很好的模型定义,所以让我们先解决这个问题:
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。这在理论上应该可行并减少查询,但如果不行,我明天会研究一下。
我有三个模型:
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_A
和 model_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 子句))?
可能重复? 有人链接的重复问题已加入两个表,使用 select_related() 很容易解决。但是它对三个表不起作用(或者我不知道在这种情况下如何使用它)。
试试这个
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)
希望对您有所帮助
当然,这不是一个很好的模型定义,所以让我们先解决这个问题:
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。这在理论上应该可行并减少查询,但如果不行,我明天会研究一下。