首页 > 解决方案 > Django Postgres JSONField 查询

问题描述

我有一个带有 json 字段的类

class A(models.Model)
    brand = JSONField()

如果我发布一个 JSON 数组,例如 [{'brand_id:1', 'name':'b1'}, {'brand_id:2', 'name':'b2'}] ,它将存储为 JSON 数组。这工作正常。

我应该如何查询以检查该数组中任何字典的brand_id中是否存在“1”?

标签: djangopython-3.xpostgresqldjango-rest-framework

解决方案


首先,您的 JSON 格式不正确。我认为它的意思是:

[{'brand_id': 1, 'name': 'b1'}, {'brand_id': 2, 'name': 'b2'}] 

如果是这种情况,要1在这样的 blob 中进行测试,类似这样的内容会告诉您是否可以在 JSON 中的任何位置1找到它作为值:

def check_for_one(json_data):
    return any([1 in data.values() for data in json_data])

但是您想具体了解JSON 中任何位置1的键是否拥有一个值, brand_id因此您还可以使用循环添加一些额外的条件:

def check_for_one(json_data):
    match = []
    for data in json_data:
        for key, value in data.items():
            if key == 'brand_id' and value == 1:
                match.append(True)
    return any(match)

您可以像这样在模型类中合并诸如方法之类的逻辑:

class A(models.Model):
    brand = JSONField()

    def check_for_one_comprehension(self):
        return any([1 in data.values() for data in self.brand])

    def check_for_one_loop(self):
        match = []
        for data in self.brand:
            for key, value in data.items():
                if key == 'brand_id' and value == 1:
                    match.append(True)
        return any(match)

但是,如果您真的想从数据库中筛选出 JSON 数据是顶层数组的实例,并且brand_id == 1,则需要一种不同的方法,应该这样做:

A.objects.filter(brand__contains=[{'brand_id': 1}])

注意额外的[{}]大括号!如果您只是调用contains=['brand_id': 1]它将引发语法错误,并且如果您调用contains={'brand_id': 1}它将不匹配。


推荐阅读