开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜