Django фильтрация запросов с Q - PullRequest
0 голосов
/ 30 января 2020

У меня запутанная проблема при запросе в django. Я знаю, что это не ошибка, и это то, чего я не знаю.

Итак, модели:

class Product(models.Model):
    name = models.CharField(max_length=255)

class AttributeValue(models.Model):
    value = models.CharField(max_length=255)
    product = models.ForeignKey(Product, related_name='attribute_values', on_delete=models.CASCADE)

У меня есть один объект под названием Футболка , и у него есть два AttributeValue с идентификаторами 1, 2. И когда я Фильтруйте так (1):

Product.objects.filter(Q(attribute_values__pk__in=[1, 2]))

Возвращает мой футболку объект. Но когда я фильтрую вот так (2)

Product.objects.filter(Q(attribute_values__pk__in=[1]) & Q(attribute_values__pk__in=[2]))

, здесь не найдено ни одного набора запросов. Как это происходит? Предыдущие коды являются лишь примерами, и у меня есть проект, который действительно нужно сделать с этим вторым фильтром (2).

Ответы [ 2 ]

4 голосов
/ 30 января 2020

Это никогда не даст результатов запроса:

Product.objects.filter(Q(attribute_values__pk__in=[1]) & Q(attribute_values__pk__in=[2]))

# Equivalent to:
Product.objects.filter(attribute_values__pk=1).filter(attribute_values__pk=2)

Почему? Потому что нет объекта, который одновременно обладает как первичным ключом 1, так и первичным ключом 2.

Вы хотите, чтобы объекты Q были объединены как "ИЛИ" вместо "И", так что это то, что вы на самом деле хотите:

Product.objects.filter(Q(attribute_values__pk__in=[1]) | Q(attribute_values__pk__in=[2]))

Но зачем использовать Q объекты, когда вы можете достичь того же без них? Например:

Product.objects.filter(attribute_values__pk__in=[1, 2])
0 голосов
/ 30 января 2020

В этом

Product.objects.filter(Q(attribute_values__pk__in=[1]), Q(attribute_values__pk__in=[2]))

вы используете выражение Q с, которое не задает желаемого значения для ожидаемого результата:

Product.objects.filter(Q(attribute_values__pk__in=[1, 2]))

или

Product.objects.filter(Q(attribute_values__pk__in=[1]) | Q(attribute_values__pk__in=[2]))

но вы должны использовать первый без выражения Q

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...