Python Django 1.9 JSONField order_by
我有以下django模型,其中包含JSONField: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
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,
)
)