【问题标题】:How do I filter Django models to only include models that appear in a child (with a ForeignKey) table?如何过滤 Django 模型以仅包含出现在子表(带有 ForeignKey)表中的模型?
【发布时间】:2019-01-19 15:26:45
【问题描述】:

我有这两个 Django 模型:

class Animals(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.TextField(unique=True)
    class Meta:
        db_table = 'animals'

class AnimalSounds(models.Model):
    id = models.AutoField(primary_key=True)
    animal = models.ForeignKey(Animal, on_delete=models.PROTECT)
    sound = models.TextField(unique=True)
    class Meta:
        db_table = 'animal_sounds'

现在我的 SQL 查询看起来像这样:

SELECT * FROM animals WHERE animals.id IN (
    SELECT animal_id FROM animal_sounds
)

我将如何使用 Django 模型来做到这一点?从概念上讲是这样的:

Animals.objects.filter(id__in=AnimalSounds.objects.all('ids'))

【问题讨论】:

    标签: sql django python-3.x postgresql django-models


    【解决方案1】:

    您可以检查是否至少有一个AnimalSound与:

    Animal.objects.filter(<b>animalsounds__isnull=False</b>).distinct()

    这将执行如下查询:

    SELECT DISTINCT animal.*
    FROM animal AS ani
    JOIN animalsounds AS ans ON ans.animal_id = ani.id
    

    或者你可以使用你的方法:

    Animals.objects.filter(
        id__in=AnimalSounds.objects.values('animal_id', flat=True)
    )

    但我更喜欢前者,因为它更具声明性且更短。

    EDIT:如果你想选择all Animals 有一个相关的AnimalSounds 对象,其中sound'woof',你可以写它喜欢:

    # animals that produce woof (and perhaps other sounds)
    Animal.objects.filter(animalsounds__sound='woof').distinct()

    【讨论】:

    • 太棒了。现在如果我想做这个查询怎么样:SELECT * FROM animals WHERE animals.id IN ( SELECT animal_id FROM animal_sounds WHERE sound = 'woof' ) 这可能吗?
    • @superdee: 然后你添加一个额外的元素到过滤器animalsounds__sound='woof'
    猜你喜欢
    • 2019-04-30
    • 2020-01-19
    • 2018-08-29
    • 2011-07-12
    • 2010-09-20
    • 2017-12-04
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多