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?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…