Each Answer to this Q is separated by one/two green lines.
Very often I see constructs like
which will return a QuerySet of the default Mananger. At first
all() seems to be quite redundant, because
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:
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.objectsreturn? Does this statement call
all()? or `get_queryset()?
Do you prefer
MyModel.objects.all().filter(...). And if so, why?
Have you ever encountered wonky managers that would mess with those methods in a undesirable way?
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()
For example, if you want to iterate over all the items, you can’t do this:
for item in MyModel.objects: # do something with item
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 something 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
exclude(), you would already have the QuerySet, because these methods are proxied to the QuerySet. So you don’t have to do something like
MyModel.objectsreturns the manager instance.
get_query_set(). I think all is there for when you need all objects.
- I prefer
MyModel.objects.filter()cause the other is just one more method call, and I don’t need all objects if I do filter 🙂
- It depends on the purpose. But if they override a base method of the manager, they return the same result format (eg. a QuerySet)
Mymodel.objects.filter(username="abcd") will give list of match record
Mymodel.objects.get(pk='abcd') will return single record with matching on primary key value