是否可以使用 Django ORM 来 select no table 字段只接收基于真实列计算的值?

Is it possible to use Django ORM to select no table fields receiving only values calculated based on real columns?

所以问题是"is it possible to make the following query using Django ORM without raw statements?"

SELECT
 my_table.column_a + my_table.column_b
FROM
 my_table

示例 从我的角度来看它会是 suitable:

我们有一个模型:

class MyOperations(models.Model):
    operation_start_time = models.DateTimeField()

在某些时候我们创建一条记录并将字段值设置为 Now(或者我们更新一些现有记录。没关系):

MyOperations.objects.create(operation_start_time=functions.Now())

现在我们想知道已经过了多少时间。我希望 Django ORM 生成以下 SQL 语句来从数据库请求数据(假设我们使用 MySQL 后端):

SELECT
 TIMESTAMPDIFF(MICROSECOND, `myapp_myoperations`.`operation_start_time`, CURRENT_TIMESTAMP) AS `time_spent`
FROM
 `myapp_myoperations`
WHERE ...

那么这是一种无需原始语句即可实现此目的的方法吗?

现在我确定了以下解决方案:

MyOperations.objects.values('operation_start_time').annotate(
    diff=ExpressionWrapper(functions.Now() - F('operation_start_time'),
    output_field=DurationField()
)).filter(...)

它产生以下 SQL 语句:

SELECT
 `myapp_myoperations`.`operation_start_time`,
 TIMESTAMPDIFF(MICROSECOND, `myapp_myoperations`.`operation_start_time`, CURRENT_TIMESTAMP) AS `time_spent`
FROM
 `myapp_myoperations`
WHERE ...

或者在Python响应对象表示中:

{'operation_start_time': datetime(...), 'diff': timedelta(...)}

是否可以仅使用 diff 来获取响应指令,因为这是我唯一感兴趣的字段? Django ORM 生成了请求 operation_start_time 的查询,就像我们写的那样。但是如果我完全删除对 values 的调用,它会生成请求所有 table 列的查询

解决方案 产生预期的 SQL

我们应该将对 values 的调用放在查询已知 diff 的地方

MyOperations.objects.annotate(
    diff=ExpressionWrapper(functions.Now() - F('operation_start_time'),
    output_field=DurationField()
)).values('diff').filter(...)

您可以在您的计算字段上使用 values(),因此查询如

MyOperations.objects.values('operation_start_time').annotate(
    diff=ExpressionWrapper(functions.Now() - F('operation_start_time'),
    output_field=DurationField()
)).values('diff')

应该给你一个结果查询集,只包含你计算的 'diff'。