我有一个简单的模型设置如下,
import random
import string
from django.db import models
def random_default():
random_str = "".join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))
return {"random": random_str, "total_price": random.randint(1, 100)}
class Foo(models.Model):
cart = models.JSONField(default=random_default)
我想从所有Foo
示例中获取***total_price
***的总和。在原生Python中,我可以做下面这样的事情来获得总和,但我认为这是次优的。
sum(foo.cart["total_price"] for foo in Foo.objects.all())
我用Django尝试了以下聚合查询,但没有一个是正确的/有效的。
1.
Foo.objects.aggregate(total=models.Sum(Cast('cart__total_price', output_field=models.IntegerField())))
# Error
# django.db.utils.DataError: cannot cast jsonb object to type integer
2.
Foo.objects.aggregate(total=models.Sum('cart__total_price', output_field=models.IntegerField()))
# Error
# django.db.utils.ProgrammingError: function sum(jsonb) does not exist
# LINE 1: SELECT SUM("core_foo"."cart") AS "total" FROM "core_foo"
^
# HINT: No function matches the given name and argument types. You might need to add explicit type casts.
提问
获取JSONField的顶级JSON键的总和的正确/最佳方法是什么?
版本号
- Python 3.8
- Django 3.1
2条答案
按热度按时间7rtdyuoh1#
您可以使用KeyTextTransform和聚合函数来实现。
使用KeyTextTransform从**'cart'JSON字段中提取'total_price'键的值。
然后,使用Sum函数和Cast**函数聚合提取值的总和,将值转换为整数。
relj7zay2#
我为***
jsonb_extract_path_text(...)
***创建了一个自定义DB函数并用作