Django: ORM中原生JSONField的使用方法 models存储json格式的数据Django: ORM中原生JSONField的使用方法 models存储json格式的数据Django: ORM中原生JSONField的使用方法 models存储json格式的数据Django: ORM中原生JSONField的使用方法 models存储json格式的数据
  • 首页
  • 博客
  • 文件
  • 书签
  • 分析
  • 登录
Search
Generic filters

Django: ORM中原生JSONField的使用方法 models存储json格式的数据

Published by admin at 2022年7月28日
Categories
  • Django
Tags
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>]>

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Categories

  • 猫
  • Python
  • MySQL
  • Django
  • Html/CSS
  • JavaScript
  • Vue
  • RegExp
  • php
  • Practice
  • Virtualization
  • Linux
  • Windows
  • Android
  • NAS
  • Software
  • Hardware
  • Network
  • Router
  • Office
  • WordPress
  • SEO
  • English
  • Games
  • Recipes
  • living
  • Memorandum
  • Essays
  • 未分类

归档

©2015-2022 Alaica Blog support@alaica.com