首页 > 解决方案 > 使用 Django 的 Q 查询过滤多对多关系

问题描述

我有一个模型

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 查询搜索说,“只向我显示该书的任何作者在其姓氏的任何部分都有查询字符串的书”?

标签: pythondjangodjango-viewsdjango-q

解决方案


您可以通过两个连续的下划线 ( ) 来“查看”关系__。因此,您可以在这里过滤last_name作者包含特定子字符串的书籍:

Book.objects.filter(
    authors__last_name__icontains=query
)

如果您因此查找Book标题包含给定 的 s query或者其中last_name一位作者的 包含query,那么您可以使用以下内容进行过滤:

Book.objects.filter(
    Q(title__icontains=query) |
    Q(authors__last_name__icontains=query)
)

推荐阅读