【Django】执行查询——查询JSONField

JSONField

本篇的例子以下面这个模型为基础:

from django.db import models


class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = models.JSONField(null=True)

    def __str__(self):
        return self.name

保存和查询None值

在使用JSONField时,要注意空值的处理,注意区分SQL NULLJSON null

保存None值

我们首先创建两个Dog实例

from django.db.models import Value, JSONField

>>> Dog.objects.create(name="Max", data=None)  # SQL NULL.
<Dog: Max>
>>> Dog.objects.create(name="Archie", data=Value(None, JSONField()))  # JSON null.
<Dog: Archie>

观察两个实例在数据库中的表现,可以发现SQL NULLJSON null是不一样的。
在这里插入图片描述

查询None值

查询时,None值将被解释为JSON null,要查询SQL NULL,需要使用isnull

>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value(None, JSONField()))
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data__isnull=True)
<QuerySet [<Dog: Max>]>
>>> Dog.objects.filter(data__isnull=False)
<QuerySet [<Dog: Archie>]>

对比可以发现,data=None在保存时存储为SQL NULL,查询时解释为JSON null

根据键值查找

根据json数据的键进行查找,用__连接,可以多个键连接一起,如果某个值是一个列表,要进行索引,就用整数代表该列表的索引。
例子:

>>> Dog.objects.create(
...     name="Rufus",
...     data={
...         "breed": "labrador",
...         "owner": {
...             "name": "Bob",
...             "other_pets": [
...                 {
...                     "name": "Fishy",
...                 }
...             ],
...         },
...     },
... )
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": None})
<Dog: Meg>
# __连接键进行查找
>>> Dog.objects.filter(data__breed="collie")
<QuerySet [<Dog: Meg>]>
#  多个键连接进行查找
>>> Dog.objects.filter(data__owner__name="Bob")
<QuerySet [<Dog: Rufus>]>
#  某个值是一个列表,要进行索引,就用整数代表该列表的索引
>>> Dog.objects.filter(data__owner__other_pets__0__name="Fishy")
<QuerySet [<Dog: Rufus>]>
# 查询缺少的键,使用isnull查找
>>> Dog.objects.create(name="Shep", data={"breed": "collie"})
<Dog: Shep>
>>> Dog.objects.filter(data__owner__isnull=True)
<QuerySet [<Dog: Shep>]>

包含与键查找

contains

contains 查询返回的对象是那些包含给定键值对的顶层字段的对象。

>>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
<Dog: Meg>
>>> Dog.objects.create(name="Fred", data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contains={"owner": "Bob"})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
>>> Dog.objects.filter(data__contains={"breed": "collie"})
<QuerySet [<Dog: Meg>]>

contained_by

这个可以理解为 contains 查询的反向。 要查询的对象满足这样的条件:其该字段对应的数据是传递的值的子集。

>>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
<Dog: Meg>
>>> Dog.objects.create(name="Fred", data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contained_by={"breed": "collie", "owner": "Bob"})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
>>> Dog.objects.filter(data__contained_by={"breed": "collie"})
<QuerySet [<Dog: Fred>]>

has_key

返回数据顶层的键中有给定值的对象。

>>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
<Dog: Meg>
>>> Dog.objects.filter(data__has_key="owner")
<QuerySet [<Dog: Meg>]>

has_keys

返回数据顶层的键都包含在给定列表中的对象。

>>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
<Dog: Meg>
>>> Dog.objects.filter(data__has_keys=["breed", "owner"])
<QuerySet [<Dog: Meg>]>

has_any_keys

返回数据顶层的键中有至少1个在给定列表中的对象,比has_keys条件更宽松。

>>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"owner": "Bob"})
<Dog: Meg>
>>> Dog.objects.filter(data__has_any_keys=["owner", "breed"])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Django是一个流行的Python Web框架,它提供了许多功能来简化数据库操作和查询。在Django中,你可以使用ORM(对象关系映射)来查询数据库。ORM允许你将数据模型与数据库表分开,从而使得数据库操作更加灵活和易于管理。 Django提供了许多内置的数据库查询工具,包括以下几种: 1. 查询构建器:Django提供了强大的查询构建器,允许你使用SQL语句来构建查询。你可以使用`QuerySet`对象来构建查询,它提供了许多方法来过滤、排序、分组和连接数据。 2. 过滤器:Django查询构建器支持各种过滤器,例如`filter()`、`exclude()`、`order_by()`等,这些方法允许你根据条件对数据进行筛选和排序。 3. 关联查询Django支持关联查询,可以方便地查询多个表之间的关联数据。你可以使用`select_related()`、`prefetch_related()`等方法来执行关联查询,以提高性能和减少数据库交互次数。 4. 聚合查询Django查询构建器还支持聚合查询,可以用于计算总和、平均值、计数等统计信息。你可以使用`annotate()`、`aggregate()`等方法来进行聚合查询。 5. 数据库迁移:Django提供了数据库迁移工具,可以帮助你在开发过程中轻松地更新数据库结构。你可以使用`makemigrations`和`migrate`命令来创建和执行迁移文件,以更新数据库结构。 下面是一个简单的示例,展示了如何在Django中使用查询构建器和过滤器进行数据库查询: ```python from myapp.models import MyModel # 获取所有满足条件的模型实例 queryset = MyModel.objects.filter(status=1) # 按照指定字段排序 queryset = queryset.order_by('created_at') # 获取指定字段的总数 total = queryset.count() ``` 这只是一些基本的介绍,Django还提供了更多高级的查询功能和工具,可以根据具体需求进行学习和使用。你可以参考Django官方文档和教程,以获取更多关于数据库查询的详细信息和示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个甜甜的大橙子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值