Python Django 1.9 JSONField order_by

Python Django 1.9 JSONField order_by,python,django,django-1.9,django-jsonfield,Python,Django,Django 1.9,Django Jsonfield,我有以下django模型,其中包含JSONField: class RatebookDataEntry(models.Model): data = JSONField(blank=True, default=[]) last_update = models.DateTimeField(auto_now=True) class Meta: verbose_name_plural = 'Ratebook data entries' 而数据字段包含以下jso

我有以下django模型,其中包含JSONField:

class RatebookDataEntry(models.Model):
    data = JSONField(blank=True, default=[])
    last_update = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = 'Ratebook data entries'
数据字段包含以下json:

{
    "annual_mileage": 15000, 
    "description": "LEON DIESEL SPORT COUPE", 
    "body_style": "Coupe", 
    "range_name": "LEON", 
    "co2_gkm_max": 122, 
    "manufacturer_name": "SEAT"
}
我可以按其中一个数据字段对queryset进行排序吗?此查询不起作用

RatebookDataEntry.objects.all().order_by("data__manufacturer_name")

文件中没有提到这种可能性。目前,您似乎无法使用基于JSONfield的order\u by。

正如Julien提到的,Django还不支持JSONfield上的排序。但这是可能的,通过使用。就OP而言:

from django.db.models.expressions import RawSQL
RatebookDataEntry.objects.all().order_by(RawSQL("data->>%s", ("manufacturer_name",)))
在回答和评论之后,您应该能够使用
RawSQL
OrderBy
对JSON数据字段上的ASC和DESC进行排序,而无需注释查询集。此外,您还可以通过添加
LOWER
,执行不区分大小写的排序:

from django.db.models.expressions import RawSQL, OrderBy

RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("LOWER(data->>%s)", ("manufacturer_name",)), descending=True))
要比较整数字段,可以强制转换为整数:

RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("cast(data->>%s as integer)", ("annual_mileage",)), descending=True))

这是一个即将推出的功能,已经添加并将在Django 2.1中发布,预计于2018年8月发布

有关详细信息,请参见和。

自Django 1.11以来,可以使用它来代替
RawSQL

from django.contrib.postgres.fields.jsonb import KeyTextTransform

qs = RatebookEntry.objects.all()
qs = qs.annotate(manufacturer_name=KeyTextTransform('manufacturer_name', 'data'))
qs = qs.order_by('manufacturer_name')
# or...
qs = qs.order_by('-manufacturer_name')
在Django 1.10上,您必须自己创建子类
KeyTransform

from django.contrib.postgres.fields.jsonb import KeyTransform

class KeyTextTransform(KeyTransform):
    operator = '->>'
    nested_operator = '#>>'
    _output_field = TextField()
注意:
KeyTransform
KeyTextTransform
之间的区别在于
KeyTransform
将返回对象的JSON表示,而
KeyTextTransform
将返回对象的值


例如,如果
data
{“test”:“stuff”}
KeyTextTransform
将返回
'stuff'
,而
KeyTransform
将返回
''stuff'
(可以通过
json.loads
解析)

我必须按日期顺序执行以下操作(使用
到日期
)。假设
数据
中有另一个值,称为
创建日期
(例如2019年6月3日)

这个问题(以及大多数答案)是针对Django 1.9的。但是,Django版本3.1和更新版本支持MariaDB、MySQL、Oracle、PostgreSQL和SQLite的
JSONField

在JSON字段上创建/维护索引的行为可能因数据库引擎而异,但排序应与您所问的语法一致:

RatebookDataEntry.objects.all().order\u by(“数据\u制造商\u名称”)

请注意,除非您进行进一步筛选,否则这将包括
data
JSONField中的
manufacturer\u name
键不存在的数据库行。

据我所知(在查询集上),但这种情况向我表明,您可能实际上需要“data”的对象模型,而不是json,使用
default=list
而不是
default=[]
,否则您将在不同实例之间共享相同的列表。如果您想要描述排序,您可以引入带注释的字段并按其排序。如下所示:RatebookDataEntry.objects.annotate(制造商名称=RawSQL(“数据->>%s”(“制造商名称”)).orderby(“-manufacturer名称”)万一有人只是在看接受的答案,这是Django 2.1中的一个功能,请参阅我的答案以获取链接。但这对MySQL不起作用,MySQL有什么解决办法吗?如果您想对数值进行排序,请使用
->
而不是
->
。(
->
)def我需要的应该是首选答案我的json字段有以下格式的数据,如何使用它根据字典中的第一个ip地址进行排序?
RatebookDataEntry.objects.all().order_by(
        OrderBy(
            RawSQL("to_date(values->>%s, 'DD.MM.YYYY')", ("created_date",)),
            descending=True,
        )
    )