有没有办法过滤类中的相关对象。我不是在谈论过滤BY相关对象,而是在类中过滤相关对象本身。也许一个例子可以更好地说明:
说我有以下型号:
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey('Author', null=True)
isbn = models.CharField('ISBN',max_length=13)
genre = models.ManyToManyField(Genre)
class Genre(models.Model):
name = models.CharField(max_length=200)
...
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('Died', null=True, blank=True)
我知道如何进行直接过滤,例如获取特定类型的所有书籍:
books = Books.objects.filter(genre=1)
然后在视图中循环显示:
{% for book in books %}
{{book.title}}
{% endfor %}
但是,有没有办法过滤查询集的相关对象?我们假设我已经过滤了作者查询集,我只想列出他的书籍来自特定类型:
如果我这样做:
{% for book in author.books_set.all %}
{{book.title}}
{% endfor %}
我得到他所有的书(正如我所期望的那样)。
但是,有没有办法做这样的事情:
{% for book in author.books_set.filter(genre=1) %}
{{book.title}}
{% endfor %}
这样我才能获得相关对象的过滤列表?
我更喜欢在视图中或作为类方法执行此操作,因为我不喜欢在模板中混合逻辑。
即:
{% for book in author.books.filtered_genres %}
{{book.title}}
{% endfor %}
但是,我似乎无法找到最好和最pythonic(或djangonic :))方法来做到这一点。
我知道我可以建造'通过循环遍历各种查询集并构建我想要的东西,我自己在视图中的数据结构,但我希望保留已定义的数据模型和关系。
对我想要完成的任何想法?或者我可以更好地阐述我想要做的事情吗?
谢谢!
答案 0 :(得分:2)
您可以在Book
模型的查询集中应用或连接多个过滤器:
books = Books.objects.filter(author='Bob', genre=1)
或
books = Books.objects.filter(author='Bob').filter(genre=1)
或 - 如果要查询相关对象 - 可以使用prefetch_related
方法:
author_genre_books = Author.objects.filter(author='Bob').prefetch_related(book_set__genre=1)
答案 1 :(得分:0)
@Doru:
我无法让这个工作,
出错了auths = Author.objects.filter(author='Bob').prefetch_related(book__genre=1)
TypeError: prefetch_related() got an unexpected keyword argument 'book__genre'
但是,你让我走上了正确的道路!我在文档中找到了 预取 方法 这就是我所做的,并让它按照我的需要运作:
auths = Author.objects.filter(author='Bob').prefetch_related(Prefetch('book_set', queryset=Book.objects.filter(genre=3), to_attr='filtered_books'))
然后在模板中使用了以下内容:
{% for book in author.filtered_books %}
{{book.title}}
{% endfor %}
所以,谢谢你让我走上正确的道路!