如何查询和比较对象上JSONbField的值?

时间:2019-07-11 10:45:50

标签: python django python-3.x django-models

我有一个包含jsonbfield的模型,需要查询字典的值。在查询中,我需要确保字典的所有值均为None,或整个字段为None。

我的模型如下:

MyModel(models.Model):
    date_created=DatetimeField()
    json_dict = JSONField(default=dict, null=True)

基本上我想得到类似的东西:

MyModel.objects.filter(Q(json_dict={}) |Q(json_dict=None) | Q(all(v=None for v in json_dict.values())))

最重要的部分是

Q(all(v=None for v in json_dict.values()))

但是我无法在查询中做到这一点。我想知道是否有一种方法可以在将结果保留在查询集中的同时进行检查,而不是将其评估为列表并在其中进行检查。

限制:

  • 我不知道字典的键,因为MyModel中每个对象的键都不同。
  • 我必须能够使用bulk_create函数,所以不能选择覆盖保存

2 个答案:

答案 0 :(得分:1)

我认为,关于效果,最好的选择是创建一个新的计算字段并对其进行过滤:

MyModel(models.Model):
    date_created=DatetimeField()
    json_dict = JSONField(default=dict, null=True)
    is_empty = BooleanField(default=True, editable=False) #<-calculated field.

    def save(self, *args, **kwargs):
        self.is_empty = ( self.metadata is None or 
                          # self.json_dict=={} or ## other checks
                          all(v is None for v in self.json_dict.values()) )
        super().save(*args, **kwargs)  

现在,您的查询非常简单,并且索引友好

MyModel.objects.filter( is_empty = True )

django Overriding predefined model methods文档中的更多信息。

答案 1 :(得分:0)

正如docs所说,您可以 定义可调用的默认值,例如pthread。话虽如此,我相信您应该使用dict作为默认值,并且如果字段为空,则可以使用它进行过滤。像这样:

dict