Django:如何通过相关对象字段的组合来过滤查询集?

问题描述 投票:0回答:1

我有三个相关模型,如下所示:

class Library(models.Model):
    name = models.CharField(max_length=200, blank=False)

    class Meta:
        verbose_name = 'library'
        verbose_name_plural = 'libraries'


class Section(models.Model):
    name = models.CharField(max_length=200, blank=False)
    library = models.ForeignField(Library, related_name='sections', on_delete=models.CASCADE, null=False)

    class Meta:
        verbose_name = 'section'
        verbose_name_plural = 'sections'


class Book(models.Model):
    title = models.CharField(max_length=200, blank=False)
    section = models.ForeignField(Section, related_name='books', on_delete=models.CASCADE, null=False)
    is_available = models.BooleanField(default=True)

    class Meta:
        verbose_name = 'book'
        verbose_name_plural = 'books'

并说我需要过滤所有拥有标题为“指环王”的书籍的图书馆。

如果我创建这样的请求

queryset = Library.objects.filter(sections__books__title="The Lord of the Rings", sections__books__is_available=True).distinct()

它将包括有我的书但不可用的图书馆,因为过滤条件不适用于同一本书。

如何指定我需要两个过滤器来组合相关对象?

python django django-queryset django-orm
1个回答
2
投票

它将包括有我的书但不可用的图书馆,因为过滤条件不适用于同一本书。

确实适用于同一本书。如果您在 same

.filter(…)
 [Django-doc] 调用中指定此项,它将应用于 same 书。

因此,它将进行如下查询:

SELECT DISTINCT library.*
FROM library
LEFT OUTER JOIN section ON section.library_id = library.id
LEFT OUTER JOIN book ON book.section_id = section.id
WHERE book.title = 'The Lord of the Rings'
  AND book.is_available

如果您想将其应用到不同的

Book
,那么您可以在两个
.filter(…)
调用中指定它,因此
Library.objects.filter(sections__books__title='The Lord of the Rings').filter(sections__books__is_available=True).distinct()
,总共四个
LEFT OUTER JOIN
。但这不是你想要的。如果您想添加额外的过滤,那么您可以在同一个
.filter(…)
调用中或在同一个
Q
对象[Django-doc]
中执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.