使用 Django 的 Q 查询过滤多对多关系

Filtering a many-to-many relationship with Django's Q query

我有模型

class Book(models.Model):

    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author)

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

我有一个看法

class SearchResultsListView(ListView):
    model = Book
    context_object_name = 'book_list'
    template_name = 'book/search_results.html'

    def get_queryset(self):
        query = self.request.GET.get('q')
        return Book.objects.filter(
            Q(title__icontains=query)
        )

我不知道如何访问外键。如何进行 Q 查询搜索 "show me only books in which any authors of the book that have the query string in any part of their last name"?

您可以查看 "through" 具有两个连续下划线 (__) 的关系。因此,您可以在此处过滤作者的 last_name 包含特定子字符串的书籍:

Book.objects.filter(
    <b>authors__last_name__icontains=query</b>
)

如果您因此查找 Books,其中标题包含给定的 query 其中一位作者的 last_name包含 query,那么您可以过滤:

Book.objects.filter(
    Q(title__icontains=query) <b>|</b>
    <b>Q(authors__last_name__icontains=query)</b>
)