【问题标题】:Django QuerySet: Why can't I filter an annotated QuerySet?Django QuerySet:为什么我不能过滤带注释的 QuerySet?
【发布时间】:2011-08-15 04:01:11
【问题描述】:

我正在尝试检索我的数据库中 100 种最受欢迎​​的书籍的列表,然后创建该列表中唯一类别的列表。以下是我简化的 Book、Favorite 和 Category 模型:

class Book(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category)

class Favorite(models.Model):
    user = models.ForeignKey(User)
    book = models.ForeignKey(Book)

class Category(models.Model):
    name = models.CharField(max_length=100)

我可以使用以下查询轻松获得 100 本书最受欢迎的列表:

books =  Book.objects.annotate(num_favorites=Count('favorite')).order_by('-num_favorites')[:100]

但是当我尝试获取这 100 种最受欢迎​​书籍的独特类别列表时,我开始遇到问题。以下查询不起作用(错误发布在下面),我似乎无法弄清楚原因。

>>> categories = Category.objects.filter(book__in=books).distinct()
>>> categories


FieldError: Cannot resolve keyword 'num_favorites' into field. Choices are: category, favorite, id, name

谁能解释一下我在这里遗漏了什么?

【问题讨论】:

    标签: mysql django django-models django-queryset


    【解决方案1】:

    您可能在一个查询中堆积了太多东西。尝试拆分它:

    book_ids = (Book.objects.annotate(num_favorites=Count('favorite'))
        .order_by('-num_favorites')[:100].values_list('id', flat=True))
    categories = Category.objects.filter(book__in=book_ids).distinct()
    

    【讨论】:

    • 感谢@Mike,我试过了,第一个查询book_ids = (Book.objects.annotate(num_favorites=Count('favorite')) .order_by('-num_favorites')[:100].values_list('id', flat=True)) 给了我同样的错误:FieldError: Cannot resolve keyword 'num_favorites' into field. 真令人费解......
    • 我可以使用books_list = Book.objects.annotate(num_favorites=Count('favorite')).order_by('-num_favorites')[:100].values_list('id', 'num_favorites') 获取多字段值列表,但是当我尝试查找唯一类别时,这会给我一个TypeError: Cannot use a multi-field ValuesListQuerySet as a filter value. 错误。
    • 可以list(Book.objects.annotate(num_favorites=Count('favorite')).order_by('-num_favorites')[:100])吗?
    • 行得通!谢谢!知道为什么这不适用于 QuerySets 吗?
    • 可能是因为 Django 太复杂了,无法将 SQL 作为一个查询来计算。请记住,Django 必须将自己限制在所有不同 SQL 中的任何工作。
    猜你喜欢
    • 2023-03-30
    • 2016-09-07
    • 2014-07-13
    • 2014-12-28
    • 2018-10-09
    • 2018-12-30
    • 2019-01-22
    • 2019-08-03
    • 2018-01-05
    相关资源
    最近更新 更多