Есть ли недостаток в использовании .filter().filter().filter() в Django?

Являются ли следующие два вызова эквивалентными SQL-запросами в Django?

Объединение нескольких вызовов

Model.objects \
.filter(arg1=foo) \
.filter(arg2=bar) \
...

Объединение всех аргументов вместе:

Model.objects \
.filter(arg1=foo, arg2=bar)

Я бы хотел, чтобы код был читабельным (намного больше вызовов фильтра, чем я показал), но только если производительность не жертвует.


person thebossman    schedule 17.09.2010    source источник


Ответы (2)


Обновлять:

Не обращайте внимания на этот ответ. Смотрите лучше, правильный ответ. Спасибо @Sam за наводку.

Старый ответ:

Являются ли следующие два вызова эквивалентными SQL-запросами в Django?

Краткий ответ: да. Они будут генерировать эквивалентные запросы.

Я проверил это на модели, которую использую. созданные запросы функционально идентичны. Различные filter условия объединяются в запросе AND вместе.

Я бы хотел, чтобы код был читабельным (намного больше вызовов фильтра, чем я показал), но только если производительность не жертвует.

Один из способов добиться удобочитаемости — использовать словарь для сбора всех условий фильтрации. Например,

conditions = dict(arg1 = foo, arg2 = bar, ....)
conditions.update(argN = baz)

Model.objects.filter(**conditions)
person Manoj Govindan    schedule 17.09.2010
comment
Это неверно для многозначных отношений. Они будут генерировать разные запросы с разными результатами при правильных условиях. См. этот ответ и связанную документацию - stackoverflow.com/a/8164920 - person Sam; 29.01.2014

В дополнение к ответу Маноджа, вот как вы можете проанализировать sql, сгенерированный для объекта QuerySet:

result1 = SomeModel.objects.filter(field1=100, field2=200)
print "Result1", results1.query

result2 = SomeModel.objects.filter(field1=100).filter(field2=200)
print "Result2", result2.query
person Sam Dolan    schedule 17.09.2010
comment
Оператор assert может работать не каждый раз. Когда я пытался, порядок предложений AND в сгенерированных запросах был другим. - person Manoj Govindan; 17.09.2010
comment
Да, ты прав, только что проверил. Удалите утверждение из ответа. - person Sam Dolan; 17.09.2010