Джанго Постгрес JSONField запрос - PullRequest
0 голосов
/ 09 мая 2018

У меня есть класс с полем json

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

Если я публикую массив JSON, например [{'brand_id: 1', 'name': 'b1'}, {'brand_id: 2', 'name': 'b2'}], он будет сохранен в виде массива JSON. Это отлично работает.

Как мне запросить, чтобы проверить, присутствует ли «1» в brand_id любого словаря в этом массиве?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Это сработало:

A.objects.filter(brands__contains=['brand_id':1])

Сначала я не проверял это с помощью массива. Ссылка, указанная @Bear Brown, дает достаточно информации. В Django это легко, но на поиски ушло время: P.

0 голосов
/ 09 мая 2018

Ну, во-первых, здесь у вас неправильный формат JSON. Я предполагаю, что это должно быть:

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

Если это так, чтобы проверить 1 в таком двоичном объекте, что-то вроде этого скажет вам, если 1 нужно найти в любом месте в JSON как значение:

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

Но вы хотите точно знать, является ли 1 значением, принадлежащим ключу brand_id в любом месте JSON, поэтому вы также можете использовать цикл для добавления некоторых дополнительных условий:

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}, он не будет совпадать.

...