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

Posted

技术标签:

【中文标题】如何使用相同的值但使用现有字段之一的不同数据类型来注释 Django Queryset?【英文标题】:How to annotate Django Queryset with the same value but with a different data type of one of existing fields? 【发布时间】:2021-08-14 09:33:17 【问题描述】:

我有一个Django model,其中有一个NumberVal 字段,即models.FloatField()

然后我需要像这样注释queryset 对象 .annotate(numberval_as_text=str(OuterRef("NumberVal"))) - 相同的值,但作为一个字符串,除了这会引发 QuerySet.annotate() received non-expression(s): OuterRef(NumberVal) 错误,这显然是正确的,但它证明了这一点。

我需要这个,因为这个注释后面跟着一个扩展的第二个注释,我在子查询过滤器中需要这个 numberval_as_text

任何提示将不胜感激。

【问题讨论】:

【参考方案1】:

在对象上调用str 显然会给你一个对象的字符串表示,因此你会得到错误。如果想输入大小写,可以使用Cast database function [Django docs]:

from django.db.models import CharField
from django.db.models.functions import Cast


queryset.annotate(numberval_as_text=Cast(OuterRef("NumberVal"), output_field=CharField(max_length=256)))

注意:除非此注解在子查询中,否则您希望使用F("NumberVal") (from django.db.models import F) 而不是 OuterRef("NumberVal")

【讨论】:

很好的答案,谢谢。最终的解决方案看起来像这样for_value_exists_related_parameter_of_a_different_type=Subquery( agr_distribution_product_parameters.annotate(numberval_as_text=Cast("NumberVal", output_field=CharField(max_length=256))).filter( Q(ProductId=object_id) & (Q(TextVal=OuterRef("DistributionParameterValueId__Code")) | Q(TextVal=OuterRef("DistributionParameterValueId__Value")) | Q(numberval_as_text=OuterRef("DistributionParameterValueId__Code")) | Q(numberval_as_text=OuterRef("DistributionParameterValueId__Value")))).values('id')[:1]【参考方案2】:

您不需要使用OuterRef。您可以只使用带有注释的普通转换。

from django.db import models
from django.db.models.functions import Cast


qs.annotate(numberval_as_text=Cast('NumberVal', output_field=models.CharField()))

【讨论】:

以上是关于如何使用相同的值但使用现有字段之一的不同数据类型来注释 Django Queryset?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除R中两列中具有相同值但ID不同的行[重复]

具有相同值但不同类型的参数的 std::floor 函数的不同值

带有 ggplots 的 for 循环生成具有相同值但标题不同的图形

加入相同的字段,不同的数据类型

在美味的视图中暴露“虚拟”字段?

求oracle中查询关联查询不同数据在另一表作为相同字段的对应的值