Django QuerySets - 如何注释一个字段但返回另一个字段?

Posted

技术标签:

【中文标题】Django QuerySets - 如何注释一个字段但返回另一个字段?【英文标题】:Django QuerySets - how to annotate off one field but return a different field? 【发布时间】:2020-11-29 00:55:56 【问题描述】:

查看文档中给出的示例:https://docs.djangoproject.com/en/3.0/topics/db/aggregation/

我的问题的相关代码(来自文档):

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()

class Publisher(models.Model):
    name = models.CharField(max_length=300)

class Book(models.Model):
    name = models.CharField(max_length=300)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    rating = models.FloatField()
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
    pubdate = models.DateField()

class Store(models.Model):
    name = models.CharField(max_length=300)
    books = models.ManyToManyField(Book)

这些示例显示了我如何在商店中获得一本书的最高价格:

>>> from django.db.models import Max, Min
>>> Store.objects.annotate(max_price=Max('books__price'))

但是,在我的情况下,我想要的是最高价格手册的名称。我该怎么办?我知道我可能会有多本最高价格的书,但对于我的用例来说,打破平局的标准并不重要。

在我的用例中,我还将 QuerySet 传递给模板,因此我更喜欢使用注释框架。

【问题讨论】:

【参考方案1】:

您可以使用Subquery expression [Django-doc]:

from django.db.models import OuterRef, Subquery

Store.objects.annotate(
    most_expensive_book_name=Subquery(
        Book.objects.filter(
            store=OuterRef('pk')
        ).values('name').order_by('-price')[:1]
    )
)

【讨论】:

以上是关于Django QuerySets - 如何注释一个字段但返回另一个字段?的主要内容,如果未能解决你的问题,请参考以下文章

Django Querysets - 添加字符串文字注释

如何使用 QuerySets 和 MySql“全文搜索”在多个字段中进行 Django 搜索?

如何测试 Django QuerySets 是不是相等?

如何使用 Django Querysets 和 Q() 与相同模型类型的对象进行比较?

python Django:QuerySets

使用 Django QuerySets 时使用列表推导而不是 for 循环