Django ORM中原生JSONField的使用方法
source link: https://blog.ops-coffee.cn/s/ukpmc39c2ysi_8j9aduoug
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
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: ops>
>>> Hero.objects.create(name='coffee', data=Value('null'))
<Hero: coffee>
>>>
>>> Hero.objects.filter(data=None)
<QuerySet [<Hero: coffee>]>
>>> Hero.objects.filter(data=Value('null'))
<QuerySet [<Hero: coffee>]>
>>>
>>> Hero.objects.get(name='ops').data
>>> Hero.objects.get(name='coffee').data
>>>
>>> Hero.objects.filter(data__isnull=True)
<QuerySet [<Hero: ops>]>
>>> Hero.objects.filter(data__isnull=False)
<QuerySet [<Hero: coffee>]>
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: ops-coffee.cn>
>>> Hero.objects.create(name='ops-coffee', data={'age':16})
<Hero: ops-coffee>
当想要查询age
为12
的数据时可以这样查询
>>> Hero.objects.filter(data__age=12)
<QuerySet [<Hero: ops-coffee.cn>]>
当想要查询group
的name
为ow1
的数据时可以这样查询
>>> Hero.objects.filter(data__group__name='ow1')
<QuerySet [<Hero: ops-coffee.cn>]>
当想要查询group
下skill
中第一个数据的name
值为swim
的数据时可以这样查询
>>> Hero.objects.filter(data__group__skill__0__name='swim')
<QuerySet [<Hero: ops-coffee.cn>]>
当想要查找包含group
键的所有数据时,可以通过has_key
来实现
>>> Hero.objects.filter(data__has_key='group')
<QuerySet [<Hero: ops-coffee.cn>]>
当想要查找同时包含group
键和age
键的所有数据时,可以通过has_keys
来实现
>>> Hero.objects.filter(data__has_keys=['group','age'])
<QuerySet [<Hero: ops-coffee.cn>]>
当想要查找包含group
键或者age
键的所有数据时,可以通过has_any_keys
来实现
>>> Hero.objects.filter(data__has_any_keys=['group','age'])
<QuerySet [<Hero: ops-coffee.cn>, <Hero: ops-coffee>]>
当想一次性查找包含age
为12
且group
的name
为ow1
的数据时,可以通过contains
来实现
>>> Hero.objects.filter(data__contains={'age':12,'group': {'name': 'ow1'}})
<QuerySet [<Hero: ops-coffee.cn>]>
JSONField除了支持以上查询方式外,对于ORM所提供的大部分其他查询方式同样支持,例如icontains
,endswith
,iendswith
,iexact
,regex
,iregex
, startswith
,istartswith
,lt
,lte
,gt
,gte
,使用起来也是非常方便
>>> Hero.objects.filter(data__age__lte=12)
<QuerySet [<Hero: ops-coffee.cn>]>
>>>
>>> Hero.objects.filter(data__group__name__startswith='ow')
<QuerySet [<Hero: ops-coffee.cn>]>
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
顺利创建了数据库表
能看到这里一定是真爱,关注一下吧
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK