What is the difference between filter with multiple arguments and chain filter in django?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Django __str__ returned non-string (type NoneType)
- Evil ctypes hack in python
As you can see in the generated SQL statements the difference is not the "OR" as some may suspect. It is how the WHERE and JOIN is placed.
Example1 (same joined table): from https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships
This will give you all the Blogs that have one entry with both
(entry__headline__contains='Lennon') AND (entry__pub_date__year=2008)
, which is what you would expect from this query.Result:
Example 2 (chained)
This will cover all the results from Example 1, but it will generate slightly more result. Because it first filters all the blogs with
(entry__headline__contains='Lennon')
and then from the result filters(entry__pub_date__year=2008)
.The difference is that it will also give you results like:
A single Blog with multiple entries
When the first filter was evaluated the book is included because of the first entry (even though it has other entries that don't match). When the second filter is evaluated the book is included because of the second entry.
One table: But if the query doesn't involve joined tables like the example from Yuji and DTing. The result is same.
There is a difference when you have request to your related object, for example
request
returns empty set
and request
returns authors that have books with both 'name1' and 'name2'
for details look at https://docs.djangoproject.com/en/dev/topics/db/queries/#s-spanning-multi-valued-relationships
The case in which results of "multiple arguments filter-query" is different then "chained-filter-query", following:
Example:
Consider my application
my_company
has two modelsEmployee
andDependent
. An employee inmy_company
can have more than dependents(in other-words a dependent can be son/daughter of a single employee, while a employee can have more than one son/daughter).Ehh, assuming like husband-wife both can't work in a
my_company
. I took 1:m exampleSo,
Employee
is referenced-model that can be referenced by more thenDependent
that is referencing-model. Now consider relation-state as follows:Now my query is:
Find all employees those having son/daughter has distinction marks (say >= 75%) in both college and school?
Output is 'A' dependent 'a1' has distinction marks in both college and school is dependent on employee 'A'. Note 'B' is not selected because nether of 'B''s child has distinction marks in both college and school. Relational algebra:
In Second, case I need a query:
Find all employees whose some of dependents has distinction marks in college and school?
This time 'B' also selected because 'B' has two children (more than one!), one has distinction mark in school 'b1' and other is has distinction mark in college 'b2'.
Order of filter doesn't matter we can also write above query as:
result is same! Relational algebra can be:
Note following:
Outputs same result:
[<Dependent: a1>]
I check target SQL query generated by Django using
print qd1.query
andprint qd2.query
both are same(Django 1.6).But semantically both are different to me. first looks like simple section σ[school_mark >= 75 AND college_mark >= 75](Dependent) and second like slow nested query: σ[school_mark >= 75](σ[college_mark >= 75](Dependent)).
If one need Code @codepad
btw, it is given in documentation @Spanning multi-valued relationships I have just added an example, I think it will be helpful for someone new.
The performance difference is huge. Try it and see.
Model.objects.filter(condition_a).filter(condition_b).filter(condition_c)
is surprisingly slow compared to
Model.objects.filter(condition_a, condition_b, condition_c)
As mentioned in "Effective Django ORM",
You can use the connection module to see the raw sql queries to compare. As explained by Yuji's, for the most part they are equivalent as shown here:
If you end up on this page looking for how to dynamically build up a django queryset with multiple chaining filters, but you need the filters to be of the
AND
type instead ofOR
, consider using Q objects.An example: