9

Are the following two calls resolved to the equivalent SQL query in Django?

Chaining multiple calls

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

Wrapping all the args together:

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

I'd like code to be readable (there are MANY more filter calls than I've shown), but only if there's no sacrifice to performance.

thebossman
  • 4,598
  • 11
  • 34
  • 45
  • Does this answer your question? [Chaining multiple filter() in Django, is this a bug?](https://stackoverflow.com/questions/8164675/chaining-multiple-filter-in-django-is-this-a-bug) – FluffyKitten Sep 30 '20 at 05:45

2 Answers2

12

Update:

Disregard this answer. See this better, correct answer. Thanks @Sam for the heads up.

Old Answer:

Are the following two calls resolved to the equivalent SQL query in Django?

Short answer: yes. They will generate equivalent queries.

I verified this with a model I am using. the queries produced are functionally identical. The different filter conditions are ANDed together in the query.

I'd like code to be readable (there are MANY more filter calls than I've shown), but only if there's no sacrifice to performance.

One way to achieve readability is to use a dictionary for collecting all filter conditions. For e.g.

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

Model.objects.filter(**conditions)
Community
  • 1
  • 1
Manoj Govindan
  • 72,339
  • 21
  • 134
  • 141
  • 8
    This is not correct for multi-valued relationships. They will generate *different* queries with *different* results given the right conditions. See this answer and the linked documentation - http://stackoverflow.com/a/8164920 – Sam Jan 29 '14 at 08:20
7

In addition to Manoj's answer, here's how you can analyze the sql generated for a QuerySet object:

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
Sam Dolan
  • 31,966
  • 10
  • 88
  • 84