假设我有一个简单的模型设置**JSONField
**
from django.db import models
import random
def simple_json_callable():
return {"amount": random.randint(1, 100)}
def nested_json_callable():
data = {
"l1": {
"l2": {
"l3": {
"amount": random.randint(1, 100)
}
}
}
}
return data
class Foo(models.Model):
simple_json = models.JSONField(default=simple_json_callable)
nested_json = models.JSONField(default=nested_json_callable)
我想从simple_json
和nested_json
字段中获得***amount
***key的和。
我尝试了以下查询
案例一:注解然后聚合
result = Foo.objects.annotate(
simple_json_amount=Cast('simple_json__amount', output_field=models.IntegerField()),
nested_json_amount=Cast('nested_json__l1__l2__l3__amount', output_field=models.IntegerField()),
).aggregate(
simple_json_total=models.Sum('simple_json_amount'),
nested_json_total=models.Sum('nested_json_amount'),
)
案例二:聚合物
result = Foo.objects.aggregate(
simple_json_total=models.Sum(Cast('simple_json__amount', output_field=models.IntegerField())),
nested_json_total=models.Sum(Cast('nested_json__l1__l2__l3__amount', output_field=models.IntegerField())),
)
在这两种情况下,我都得到了错误
django.db.utils.DataError: cannot cast jsonb object to type integer
提问
在Django中聚合JSONField
值的和的正确方法是什么?
版本号
- Django 3.1
- Python 3.9.X
1条答案
按热度按时间hc8w905p1#
Django==3.2.X
及以上版本您可以使用 “双下划线” 来跨越关系,并可以获得聚合结果(如OP中所述)
Django==3.1.X
及旧版本您可以使用**
KeyTextTransform(...)
**来提取键并聚合值。如果你正在使用***
PostgreSQL
***,并且不想使用 “KeyTextTransform
的嵌套用法“,你可以创建一个自定义Django DB函数,等价于***jsonb_extract_path_text(...)
***它可以被用作
引用
JSONField