Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 使用JSONField';s属性_Django_Django Models_Django Jsonfield - Fatal编程技术网

Django 使用JSONField';s属性

Django 使用JSONField';s属性,django,django-models,django-jsonfield,Django,Django Models,Django Jsonfield,我有一个类似这样的模型: class Person(models.Model): data = JSONField() data字段有两个属性,name和age。现在,假设我想要得到一个分页的查询集(每个页面包含20个人),带有一个过滤器,其中age大于25,查询集按降序排列。在通常的设置(即规范化数据库)中,我可以这样编写此查询: person_list_page_1 = Person.objects.filter(age > 25).order_by('-age')[:20]

我有一个类似这样的模型:

class Person(models.Model):
    data = JSONField()
data
字段有两个属性,
name
age
。现在,假设我想要得到一个分页的查询集(每个页面包含20个人),带有一个过滤器,其中
age
大于25,查询集按降序排列。在通常的设置(即规范化数据库)中,我可以这样编写此查询:

person_list_page_1 = Person.objects.filter(age > 25).order_by('-age')[:20]
现在,当使用存储在JSONField中的键进行过滤和排序时,上面的等价性是什么?我对此进行了研究,它似乎是2.1的一个特性,但我似乎找不到任何相关的东西

我还有一个问题。假设我们使用JSONField进行过滤和排序。在这种情况下,在发送前20个对象之前,ORM必须获取所有对象、过滤并对它们进行排序吗?也就是说,性能是否会合理地降低


显然,我知道规范化数据库更适合于这些事情,但我手头有点紧。

您可以使用postgresql语法来提取子字段。然后,它们可以像queryset过滤器中模型上的任何其他字段一样使用

from django.db.models.expressions import RawSQL
Person.objects.annotate(
    age=RawSQL("(data->>'age')::int", [])
).filter(age__gte=25).order_by('-age')[:20]
有关其他运算符和函数,请参见postgresql文档。 在某些情况下,您可能必须添加显式类型转换(例如,
::int


性能会比使用合适的字段慢,但也不错。

您可以使用postgresql语法提取子字段。然后,它们可以像queryset过滤器中模型上的任何其他字段一样使用

from django.db.models.expressions import RawSQL
Person.objects.annotate(
    age=RawSQL("(data->>'age')::int", [])
).filter(age__gte=25).order_by('-age')[:20]
有关其他运算符和函数,请参见postgresql文档。 在某些情况下,您可能必须添加显式类型转换(例如,
::int


性能将比使用正确的字段慢,但还不错。

您是否尝试过
。order\u by('-data\u\u age')
?@AntoinePinsard是的,我遇到了以下错误:FieldError:无法将关键字“age”解析到字段中。不允许对“数据”进行连接。如果需要按字段进行索引、筛选或排序,为什么不将其设置为适当的列/模型字段,而不是滥用jsonfields。@HåkenLid很懒地假设这是滥用jsonfields,而不知道它是什么,并且它会这样做。正如我在问题中所说,它必须是一个jsonfield,是的,我完全意识到规范化的好处。您是否尝试过
.order\u by('-data\u\u age')
?@AntoinePinsard是的,我得到这个错误:FieldError:无法将关键字“age”解析到字段中。不允许对“数据”进行连接。如果需要按字段进行索引、筛选或排序,为什么不将其设置为适当的列/模型字段,而不是滥用jsonfields。@HåkenLid很懒地假设这是滥用jsonfields,而不知道它是什么,并且它会这样做。正如我在问题中所说的,它必须是一个jsonfield,是的,我完全了解规范化的好处。关于类型转换,如果它是一个格式为“-10.50”的字符串,即存储为字符串的十进制数,该怎么办。我找不到Postgres的数字类型转换。应该可以。例如,试试
::数字(99,2)
。Django将Postgresql数值类型转换为python
Decimal
type。非常感谢,这基本上解决了我所有的问题。刚刚在10000多行上进行了测试,速度惊人!关于类型转换,如果它是一个格式为“-10.50”的字符串,即存储为字符串的十进制数,该怎么办。我找不到Postgres的数字类型转换。应该可以。例如,试试
::数字(99,2)
。Django将Postgresql数值类型转换为python
Decimal
type。非常感谢,这基本上解决了我所有的问题。刚刚在10000多行上进行了测试,速度惊人!