如何在 Django QuerySet 中注释两个字段的最大值

Posted

技术标签:

【中文标题】如何在 Django QuerySet 中注释两个字段的最大值【英文标题】:How annotate the Max value of two fields in a Django QuerySet 【发布时间】:2018-02-22 21:48:32 【问题描述】:

我有一个模型Client,我如何注释然后排序,它的两个字段的最大值:

from django.db import models

class Client(models.Model):
    uploaded_photo_at = models.DateTimeField()
    uploaded_document_at = models.DateTimeField()

以下内容:

Client.objects.annotate(
    latest_activity_at=Max('uploaded_photo_at', 'uploaded_document_at', output_field=DateTimeField())
).order_by('latest_activity_at')

引发此错误:

django.db.utils.ProgrammingError: function max(timestamp with time zone, timestamp with time zone) does not exist
LINE 1: ...oto_at", "clients_client"."uploaded_document_at", MAX("clien...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

我正在使用 Posgresql 和 Django 1.11,如果有帮助的话。

【问题讨论】:

【参考方案1】:

感谢罗伯特的回答,我找到了Greatest class of Django。

以下作品:

from django.db.models.functions import Greatest

Client.objects.annotate(
    latest_activity_at=Greatest('uploaded_photo_at', 'uploaded_document_at')
).order_by('latest_activity_at')

【讨论】:

官方文档中提到GREATEST的实现依赖于SQL后端。我发现“NULL”的处理让我感到困惑,不得不为我的用例编写额外的选择。【参考方案2】:

您好,您可以使用 django query extra 功能

qs = Client.objects.extra(select='output_field': 
                                 'GREATEST(uploaded_photo_at, uploaded_document_at)')
                   .order_by('latest_activity_at')

这将返回最大值两个字段

【讨论】:

以上是关于如何在 Django QuerySet 中注释两个字段的最大值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用相同的值但使用现有字段之一的不同数据类型来注释 Django Queryset?

如何在 django 注释中从 0 开始计数?

如何在 Django 查询集中使用条件注释 Count

Django:结合来自两个过滤器查询的两个计数注释

queryset,union,order_by 在带注释的字段上

需要根据找到的 Q 对象来注释 Django querySet