Django 过滤器是不是存在 json 中的可选键
Posted
技术标签:
【中文标题】Django 过滤器是不是存在 json 中的可选键【英文标题】:Django filter if an optional key in json existsDjango 过滤器是否存在 json 中的可选键 【发布时间】:2017-07-09 17:52:51 【问题描述】:我有一个模型 X
带有自定义 json 字段 data
,它可能有也可能没有这些键:key1
、key2
、key3
。
我需要一种使用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 中的可选键的主要内容,如果未能解决你的问题,请参考以下文章