首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Django ORM中原生JSONField的使用方法

带你尝鲜Django最新版重要更新JSONField的使用

Django最新版v3.1的主要更新之一便是完善了对JSON数据存储的支持,新增models.JSONField和forms.JSONField,可在所有受支持的数据库后端上使用

目前支持的数据库以及对应版本主要有MariaDB 10.2.7+,MySQL 5.7.8+,Oracle,PostgreSQL和SQLite 3.9.0+,但个别Django的查询方法可能与部分数据库不兼容,例如contains和contained_by就不支持Oracle和SQLite数据库

JSONField使用

from django.db import models

class Hero(models.Model):

name = models.CharField(max_length=200)

data = models.JSONField(null=True)

def __str__(self):

return self.name

通过models.JSONField可指定此字段为存储类型为JSON格式。null=True表示此字段可以为空,这个NULL指的是SQL NULL,如果想存储为JsonNULL,则可以使用Value('null')来实现

Hero.objects.create(name='coffee', data=Value('null'))

SQL NULL与JsonNULL的区别主要在is_null的查询上不同,可以通过以下这个示例来理解下

>>> from django.db.models import Value

>>>

>>> Hero.objects.create(name='ops')

>>> Hero.objects.create(name='coffee', data=Value('null'))

>>>

>>> Hero.objects.filter(data=None)

>>> Hero.objects.filter(data=Value('null'))

>>>

>>> Hero.objects.get(name='ops').data

>>> Hero.objects.get(name='coffee').data

>>>

>>> Hero.objects.filter(data__isnull=True)

>>> Hero.objects.filter(data__isnull=False)

JSONField查询

Json字段的查询方法,通过下边这个示例演示说明

>>> Hero.objects.create(name='ops-coffee.cn', data={

...     'age': 12,

...     'group': {

...         'name': 'ow1',

...         'skill': [

...             {'name': 'swim', 'rank': 'A+'},

...             {'name': 'shot', 'rank': None}

...         ]

...     }

... })

>>> Hero.objects.create(name='ops-coffee', data={'age':16})

当想要查询age为12的数据时可以这样查询

>>> Hero.objects.filter(data__age=12)

当想要查询group的name为ow1的数据时可以这样查询

>>> Hero.objects.filter(data__group__name='ow1')

当想要查询group下skill中第一个数据的name值为swim的数据时可以这样查询

>>> Hero.objects.filter(data__group__skill__0__name='swim')

当想要查找包含group键的所有数据时,可以通过has_key来实现

>>> Hero.objects.filter(data__has_key='group')

当想要查找同时包含group键和age键的所有数据时,可以通过has_keys来实现

>>> Hero.objects.filter(data__has_keys=['group','age'])

当想要查找包含group键或者age键的所有数据时,可以通过has_any_keys来实现

>>> Hero.objects.filter(data__has_any_keys=['group','age'])

当想一次性查找包含age为12且group的name为ow1的数据时,可以通过contains来实现

>>> Hero.objects.filter(data__contains={'age':12,'group': {'name': 'ow1'}})

JSONField除了支持以上查询方式外,对于ORM所提供的大部分其他查询方式同样支持,例如icontains,endswith,iendswith,iexact,regex,iregex, startswith,istartswith,lt,lte,gt,gte,使用起来也是非常方便

>>> Hero.objects.filter(data__age__lte=12)

>>>

>>> Hero.objects.filter(data__group__name__startswith='ow')

SQLite3报错处理

我在Windows下开发测试时,当migrate生成表的时候遇到了如下报错,这主要是因为SQLite不支持JSONFields导致的

SQLite does not support JSONFields

解决方法为:

先去sqlite官网下载对应的DLL软件包https://www.sqlite.org/download.html,然后替换掉当前使用的sqlite3.dll文件。例如我的windows为64位版本,所以下载了sqlite-dll-win64-x64-3320300.zip这个软件包,本地python的安装路径为C:\python36,直接将C:\python36\DLLs\sqlite3.dll用下载的软件包里的sqlite3.dll文件替换,然后再次运行migrate顺利创建了数据库表

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200811A00S8P00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券