Django 过滤器是不是存在 json 中的可选键

Posted

技术标签:

【中文标题】Django 过滤器是不是存在 json 中的可选键【英文标题】:Django filter if an optional key in json existsDjango 过滤器是否存在 json 中的可选键 【发布时间】:2017-07-09 17:52:51 【问题描述】:

我有一个模型 X 带有自定义 json 字段 data,它可能有也可能没有这些键:key1key2key3。 我需要一种使用key1 过滤所有实例的方法。

我试过这样做:

queryset = X.objects.all()
queryset = queryset.annotate(
has_key1=(
    Case(
        When(~Q(data__key1__in=[None, '']), then=True),
        default=False,
        output_field=models.BooleanField())
    )
)

但是queryset.filter(has_key1=True) 没有返回任何内容,但是有一些 key1 的记录。

直接过滤器:queryset.filter(data__key1__in=[1]) 工作正常。 任何有解决这个问题的人吗?谢谢。

【问题讨论】:

你在使用 JSONField 类的 PosgreSQL 吗?我不认为您可以使用它来搜索密钥。 这是一个自定义的 jsonfield,将 python dicts 序列化为 json dicts 并再次返回。 PG是我的数据库 其实我错了。有一个has_key方法:docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/… 如果您使用的是 PostgreSQL,为什么不直接使用 JSONField 或扩展它,而不必重写已经存在的内容? 因为JSONField不支持日期时间和其他对象类型的序列化 【参考方案1】:

您可以在 JSONField 上使用 has_key。 JSONField 和 HStoreField 共享此查找 - docs。

X.objects.filter(data__has_key='key_1')

这里是一个基于我的项目的例子,我在FilterSet(django_filters.rest_framework)中的JSONField上使用了has_key,来实现key过滤(如果key不存在则返回0个结果):

filters.py:

class XFilter(FilterSet):
   data_search_by_key =  django_filters.CharFilter(method='filter_data_key',
        help_text='Search by key')

   def filter_data_key(self, qs, name, value):
        qs = X.objects.filter(data__has_key=value)
        return qs

【讨论】:

【参考方案2】:

您可以使用以下方法排除所有 NULL 值和空字符串:

queryset  = queryset.exclude(data__key1__isnull=True).exclude(data__key1__exact='')

【讨论】:

以上是关于Django 过滤器是不是存在 json 中的可选键的主要内容,如果未能解决你的问题,请参考以下文章

django 模型中的可选字段

Maven 中的可选过滤器文件

AngularJS 表单。 JSON中的可选属性[重复]

如何检查 Postgres 中是不是存在 json 键?

ES11中的可选链等语法

ES11中的可选链等语法