What functions do the order of Django Managers affect?
So, I've read most of the docs and I've been looking around on SO a bit, but I can't quite find the answer to my question. I'll start with the code.
# Manager
class ActiveManager(models.Manager):
def get_query_set(self):
return super(ActiveManager, self).get_qu开发者_JS百科ery_set().filter(is_active=True)
# Model
class ModelA(models.Model):
# ...
is_active = models.BooleanField()
objects = ActiveManager()
all_objects = models.Manager()
So, while I was playing around I noticed that if I wrote it this way and used get_object_or_404()
, then it would use the ActiveManager
to first search for all active records and then return the one related to my query. However, if I switched the order of the managers:
class ModelA(models.Model):
# ...
all_objects = models.Manager()
objects = ActiveManager()
Then it uses the default manager, in this case all_objects
, to do the query. I'm wondering what other functions does this change impact.
EDIT: I understand that the first manager found in the class becomes the default manager, but I'm wondering which specific functions use this default manager (like get_object_or_404
)
Here's the relevant bit from the docs: "If you use custom Manager
objects, take note that the first Manager
Django encounters (in the order in which they're defined in the model) has a special status. Django interprets the first Manager
defined in a class as the "default" Manager
, and several parts of Django (including dumpdata
) will use that Manager
exclusively for that model. As a result, it's a good idea to be careful in your choice of default manager in order to avoid a situation where overriding get_query_set()
results in an inability to retrieve objects you'd like to work with".
If you look at the way get_object_or_404
is implemented, they use the _default_manager
attribute of the model, which is how Django refers to the first manager encountered. (As far as I know, all Django internals work this way -- they never use Model.objects
etc. because you shouldn't assume the default manager happens to be called objects
).
It effects many things. The default name for the manager, objects
, is just that, a default, but it's not required. If you didn't include objects
in your model definition and just defined a manager as all_objects
, ModelA.objects
wouldn't exist. Django merely assigns a default manager to that if no other managers are present on the model and you have not defined objects
on your own.
Anyways, because of this Django takes the first manager defined in a model and calls that the "default", and later uses the "default" manager anytime is needs to reference the model's manager (because, again, it can't simply use objects
because objects
might not be defined).
The rule of thumb is that the standard manager that Django should use (in a sense, the manager that should most normally be used), should be the first one defined, whether it be assigned to objects
or something else entirely. Every other additional manager should come after that.
精彩评论