Django:如何通过相关 objects 字段的组合来过滤查询集?
Django: how to filter queryset by the combination of related objects fields?
我有三个相关模型,如下所示:
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()
它将包括拥有我的书但不可用的图书馆,因为过滤条件不适用于同一本书。
如何指定我需要将两个过滤器结合起来才能获得相关 objects?
It will include libraries that have my book and it's not available, because the filter condition doesn't apply to the same book.
它适用于同一本书。如果您在 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'
<strong>AND book.is_available</strong>
如果你想将它应用到不同的 Book
,那么你在两次 .filter(…)
调用中指定它,所以 Library.objects.filter(sections__books__title='The Lord of the Rings').filter(sections__books__is_available=True).distinct()
,因此总共有四个 LEFT OUTER JOIN
]s。但这不是你想要的。如果您想添加额外的过滤,那么您可以在同一个 .filter(…)
调用或同一个 Q
object [Django-doc].
中执行此操作
我有三个相关模型,如下所示:
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()
它将包括拥有我的书但不可用的图书馆,因为过滤条件不适用于同一本书。
如何指定我需要将两个过滤器结合起来才能获得相关 objects?
It will include libraries that have my book and it's not available, because the filter condition doesn't apply to the same book.
它适用于同一本书。如果您在 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'
<strong>AND book.is_available</strong>
如果你想将它应用到不同的 Book
,那么你在两次 .filter(…)
调用中指定它,所以 Library.objects.filter(sections__books__title='The Lord of the Rings').filter(sections__books__is_available=True).distinct()
,因此总共有四个 LEFT OUTER JOIN
]s。但这不是你想要的。如果您想添加额外的过滤,那么您可以在同一个 .filter(…)
调用或同一个 Q
object [Django-doc].