【问题标题】: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不支持日期时间和其他对象类型的序列化

标签: python json django django-models


【解决方案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='')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2021-11-17
      • 2016-01-15
      • 2017-12-30
      • 2015-01-07
      • 1970-01-01
      相关资源
      最近更新 更多