Класс Django ORM Queryset ведет себя по-разному с одинаковыми фильтрами - PullRequest
0 голосов
/ 26 сентября 2018

Это простой вопрос.

Я хочу 2 фильтра одновременно с классом Queryset.Позволь мне объяснить.

from django.db.models import Q
import datetime
from .models import Asset

query_set = Asset.objects.filter(category__name="car")

date_query = {'eav__date__gte': datetime.datetime(2018, 9, 2, 0, 0), 'eav__date__lte': datetime.datetime(2018, 9, 14, 0, 0)}

number_query = {'eav__price__gte': '60', 'eav__price__lte': '600'}

total_query = {'eav__date__gte': datetime.datetime(2018, 9, 2, 0, 0), 'eav__date__lte': datetime.datetime(2018, 9, 14, 0, 0),'eav__price__gte': '60', 'eav__price__lte': '600'}

query_set = query_set.filter(Q(**number_query))

query_set = query_set.filter(Q(**date_query))

в этом случае query_set равен не пусто!


query_set = query_set.filter(Q(**total_query))

в этом случае query_set пуст!


Может кто-нибудь объяснить разницу между двумя запросами, пожалуйста?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Используйте объект Q для построения набора запросов.Самый простой способ работы с запросами в Django В вашем случае

query_set = query_set.filter(Q(**number_query))
query_set = query_set.filter(Q(**date_query))

Это разные наборы запросов.

query_set = query_set.filter(Q(**total_query))

Здесь вы объединяете два запроса без условия AND, OR, поэтому оно пустое.Здесь вы хотите И условие, я думаю, поэтому используйте это как Q (first_name__startswith = 'R') & Q (last_name__startswith = 'D')

0 голосов
/ 26 сентября 2018

Это потому, что вы фильтруете многозначные отношения.Как объясняют документы :

Django имеет согласованный способ обработки filter() вызовов.Все внутри одного вызова filter() применяется одновременно, чтобы отфильтровать элементы, соответствующие всем этим требованиям.Последовательные вызовы filter() дополнительно ограничивают набор объектов, но для многозначных отношений они применяются к любому объекту, связанному с основной моделью, не обязательно к тем объектам, которые были выбраны более ранним вызовом filter().

Итак, ваш первый случай выбирает все эти Активы с EAV, который соответствует требованиям даты и EAV, который соответствует требованиям цены, но не обязательно тот же EAV .Во втором случае выбираются только те активы, для которых существует EAV, который соответствует обоим требованиям одновременно.

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