You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何筛选JSONField内大于指定日期的多日期数据

Django JSONField 筛选包含指定日期之后的记录

假设你的模型定义如下:

from django.db import models

class MyModel(models.Model):
    dates = models.JSONField()  # Django 3.1+ 可用,低版本需用 django.contrib.postgres.fields.JSONField

方法一:PostgreSQL 原生查询(高效推荐)

如果项目使用PostgreSQL作为数据库,利用其JSONB原生支持可高效实现筛选:

方式1:ORM子查询实现

from django.db.models import Exists, OuterRef, Func
from django.db.models.fields import TextField

target_date = "2022-10-01"

# 子查询展开JSON数组,筛选其中日期大于目标值的记录
subquery = MyModel.objects.filter(
    id=OuterRef('id')
).annotate(
    date_element=Func(F('dates'), function='jsonb_array_elements_text', output_field=TextField())
).filter(
    date_element__gt=target_date
)

# 主查询获取符合条件的记录
results = MyModel.objects.filter(Exists(subquery)).distinct()

方式2:原生SQL实现

若觉得ORM写法繁琐,直接用原生SQL更直观:

target_date = "2022-10-01"
results = MyModel.objects.raw(
    """
    SELECT DISTINCT m.*
    FROM myapp_mymodel m
    JOIN jsonb_array_elements_text(m.dates) AS d(date)
    ON d.date > %s
    """,
    [target_date]
)

注意替换myapp_mymodel为你的模型对应的数据库表名(通常为应用名_模型名小写形式)。

方法二:跨数据库通用方案(适合小数据量)

如果使用SQLite、MySQL等对JSON支持较弱的数据库,需先取出所有记录,在Python层面过滤:

target_date = "2022-10-01"

filtered_records = []
for record in MyModel.objects.all():
    # 跳过数组中的空值(如示例row1里的空元素),判断是否存在大于目标日期的项
    if any(date and date > target_date for date in record.dates):
        filtered_records.append(record)

注意事项

  • 示例中row1的数组存在空值,过滤时需额外判断避免异常
  • PostgreSQL方案性能远优于Python层面过滤,数据量大时优先选择

内容的提问来源于stack exchange,提问作者samrazm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:45:37