Django、MySQL、JSONField - JSON 数据过滤问题

问题描述 投票:0回答:1

我在过滤存储在 Django JSONField 中的 JSON 数据时遇到问题。在尝试使用 icontains 查找过滤数据时,它似乎将 JSON 数据视为字符串字段,并且过滤无法按预期工作。以下是我的设置的简要概述:

型号:

我有一个带有 JSONField 的 Django 模型,如下所示:

from django.db import models

class ChatMessage(models.Model):
    template_message = models.JSONField(null=True)

JSON数据以以下格式存储在数据库中:

{
    "header": {
        "type": "text",
        "content": "Hello"
    },
    "body": "Hi there",
    "footer": "Hello there"
}

问题描述:

我面临的问题是过滤代码。我想根据 JSON 数据中的值过滤对象,但 icontains 查找似乎将其视为字符串字段而不是 JSON 字段。

ChatMessage.objects.filter(
    Q(template_message__header__content__icontains=search_key) |
    Q(template_message__body__icontains=search_key) |
    Q(template_message__footer__icontains=search_key)
)

预期结果:

我希望过滤考虑 JSON 结构,并根据任何 JSON 值(例如内容、正文或页脚字段)中是否存在

search_key
进行过滤。

错误信息:

我没有收到任何错误消息,但过滤没有按预期工作。

mysql django django-models django-filter django-jsonfield
1个回答
0
投票

使用 contains/icontains 来过滤 JSONField 值是行不通的,要达到你想要的结果,你可以使用 Substr 或 KT(Django >= 4.2)

from django.db.models import CharField, Q
from django.db.models.functions import Substr


ChatMessage.objects.annotate(
    header_content=Substr("template_message__header__content", 1, output_field=CharField()),
    body=Substr("template_message__body", 1, output_field=CharField()),
    footer=Substr("template_message__footer", 1, output_field=CharField()),
).filter(
    Q(header_content__icontains=search_key)
    | Q(body__icontains=search_key)
    | Q(footer__icontains=search_key)
)

如果您使用的是 Django >= 4.2,您可以如下使用 KT

from django.db.models.fields.json import KT
from django.db.models import Q


ChatMessage.objects.annotate(
    header_content=KT("template_message__header__content"),
    body=KT("template_message__body"),
    footer=KT("template_message__footer"),
).filter(
    Q(header_content__icontains=search_key)
    | Q(body__icontains=search_key)
    | Q(footer__icontains=search_key)
)
© www.soinside.com 2019 - 2024. All rights reserved.