Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.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
使用JSONField的属性对Django queryset进行排序,前提是该属性并非无处不在_Django_Django Orm_Django Jsonfield - Fatal编程技术网

使用JSONField的属性对Django queryset进行排序,前提是该属性并非无处不在

使用JSONField的属性对Django queryset进行排序,前提是该属性并非无处不在,django,django-orm,django-jsonfield,Django,Django Orm,Django Jsonfield,这是一个非常复杂的问题,让我解释一下。我有一个名为Person的模型,它将大部分数据存储在一个JSONField中 class Person(models.Model): data = JSONField() 现在,数据字段通常采用以下格式: {"name" : <String>, "age" : <int>} 这很好,而且效果很好。但是,在测试期间,我将one Person对象的data属性更改为如下内容: {"name" : <String>,

这是一个非常复杂的问题,让我解释一下。我有一个名为Person的模型,它将大部分数据存储在一个JSONField中

class Person(models.Model):
    data = JSONField()
现在,数据字段通常采用以下格式:

{"name" : <String>, "age" : <int>}
这很好,而且效果很好。但是,在测试期间,我将one Person对象的
data
属性更改为如下内容:

{"name" : <String>, "profession" : <String>} 

无论如何,有没有不涉及列表、itertools和链的方法来实现这一点?因为我听说他们有时会很慢

谢谢


注意:请不要回答关于为这些查询规范化数据库而不是使用JSonfield的问题。我很清楚规范化的好处,但对于我的用例,它必须是一个JSONField。

如果键查找失败,结果将是
NULL
,如以下所述:

class Person(models.Model):
    data = JSONField()
注意:json和jsonb类型都有这些运算符的并行变体。field/element/path提取运算符返回的类型与其左侧输入(json或jsonb)相同,但指定为返回文本的运算符除外,后者将值强制为文本。如果JSON输入没有与请求匹配的正确结构,则字段/元素/路径提取运算符返回
NULL
,而不是失败;例如,如果不存在这样的元素

您可以这样做,只需订购:

从django.db.models导入F,RawSQL
从。模型进口人
qs=Person.objects.annotate(
age=RawSQL(((数据->'age')::int“,[]))
).order_by(F('age').desc(nulls_last=True))
这将通过以下方式对元素进行排序:

-- SQL query
ORDER BY age IS NULL, age DESC
——SQL查询
按年龄排序的订单为空,年龄描述

因此,如果第一次按
年龄排序为空
,这将导致
为真
,因此,它将在结果表的底部排序。

非常感谢。
from django.db.models import F, RawSQL
from .models import Person

qs = Person.objects.annotate(
    age=RawSQL("(data->>'age')::int", [])
).order_by(F('age').desc(nulls_last=True))
-- SQL query
ORDER BY age IS NULL, age DESC