假设我有一个模型:
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')