Django ORM - objects.filter() vs. objects.all().filter() - which one is preferred?
django, django-managers, django-orm, django-queryset, python
Solution
The method `all()` on a manager just delegates to `get_queryset()`, as you can see in the Django source code:
def all(self):
return self.get_queryset()
So it's just a way to get the QuerySet from the Manager. This can be handy to ensure that you're dealing with a QuerySet and not a Manager, because `MyModel.objects` returns a Manager.
For example, if you want to iterate over all the items, you can't do this:
for item in MyModel.objects:
# this won't work
Because you can't iterate over a Manager. However, `all()` returns the QuerySet, you can iterate over a QuerySet:
for item in MyModel.objects.all():
# do someting with item
Generally, you should never overwrite `all()`. You can overwrite `get_queryset()` but this method must return a QuerySet.
If you would use a filter method like `filter()` or `exclude()`, you would already have the QuerySet, because these methods are proxied to the QuerySet. So you don't have to do something like `all().filter()`.
Problem
Very often I see constructs like ``` MyModel.objects.all().filter(...) ``` which will return a QuerySet of the default Mananger. At first `all()` seems to be quite redundant, because ``` MyMode.objects.filter(...) ``` delivers the same result. However, this seems to be safe for the default Manager only, because of the following two statements in the Django documentation: Excerpt from the Chapter "Adding extra manager methods" A custom Manager method can return anything you want. It doesn’t have to return a QuerySet. Definition of the `all()` manager method: all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result. After calling all() on either object, you’ll definitely have a QuerySet to work with. This seems a bit like a contradiction to me. On one hand Django offers the freedom to let a manager method return whatever object type is preferred and on the other hand it requires a QuerySet for the `all()` method. I'm aware that each manager has a `get_queryset` method which is called by `all()`. But who stops me from overriding `all()` in my custom manager? Although I agree it would be bad design to do so. So as far as I can see, the `all()` method does not guarantee to return a QuerySet. What exactly does `MyModel.objects` return? Does this statement call `all()`? or `get_queryset()? Do you prefer `MyModel.objects.filter(...)` or `MyModel.objects.all().filter(...)`. And if so, why? Have you ever encountered wonky managers that would mess with those methods in a undesirable way?