计算布尔表达式并注释结果



假设我有一个模型:

class Measurement(models.Model):
measurements = JSONField(
null=True, blank=True, help_text="Key value pairs for measurements."
)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
get_latest_by = "timestamp"

measurements中的值是具有布尔值的键值对的VARIABLE数量,但这些值也可以为null。例如:

{
"a": true,
"b": false, // optional
"c": null // optional
//etc...can be infinite amount of values.
}

我需要能够把它们放在一起。例如:

result_expression = F("measurements__a") & F("measurements__b") & F("measurements__c") & F("measurement__...")

显然,这行不通。

此外,我如何能够对结果进行注释?Measurement.objects.annotate(result=result_expression).values("result")

这里的结果应该是False,因为有null和False值。

我该怎么做?我知道我完全可以用Python来实现这一点。我宁愿不那样做。如果有Postgres或Django的方法,我宁愿这样做。

您可以使用检查这三个值是否为True

Measurement.objects.annotate(
measurements__a=True,
measurements__b=True,
measurements__c=True
).values('result')

或者您可以使用Case表达式[Django-doc]进行注释:

from django.db.models import BooleanField, Case, Value, When
Measurement.objects.annotate(
result=Case(
When(
measurements__a=True,
measurements__b=True,
measurements__c=True,
value=Value(True)
),
default=Value(False),
output_field=BooleanField()
)
).values('result')

对于数量可变的密钥,我们可以使用字典拆包:

from django.db.models import BooleanField, Case, Value, When
items = ['a', 'b', 'c']
Measurement.objects.annotate(
result=Case(
When(
**{f'measurements__{k}': True for k in items },
value=Value(True)
),
default=Value(False),
output_field=BooleanField()
)
).values('result')

最新更新