#9676 closed (fixed)
Explicit default managers
Reported by: | mrts | Owned by: | Malcolm Tredinnick |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.0 |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Design decision needed | |
Has patch: | no | Needs documentation: | yes |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Currently, "the first manager declared is the default manager".
However, given the following hierarchy:
class PublishedObjectManager(models.Manager): def get_query_set(self): return super(PublishedObjectManager, self).get_query_set()\ .filter(is_published=True) class PublicationBase(models.Model): ... objects = models.Manager() published_objects = PublishedObjectManager() class Meta: abstract = True class ToplevelPageManager(PublishedObjectManager): def get_query_set(self): return super(ToplevelPageManager, self).get_query_set()\ .filter(parent=None) class PageBase(PublicationBase): ... toplevel_pages = ToplevelPageManager() class Meta: abstract = True
all classes inheriting from PageBase
get toplevel_pages
as their
default manager.
To make objects
default, repetition is necessary:
class PageBase(PublicationBase): ... objects = models.Manager() toplevel_pages = ToplevelPageManager() class Meta: abstract = True
only to specify the default manager. A way to explicitly say
"this is the default manager that should be honoured throughout the
inheritance hierarchy" would be appropriate. Also, the _
in front of
_default_manager
implies that it is an implementation detail, neither is
accessing default managers documented. But all reusable app
writers should really use model._default_manager
instead of
model.objects
for any foreign models they must handle.
Generally, there should be an explicit, documented way to set and get
the default manager.
Change History (7)
comment:1 by , 16 years ago
Needs documentation: | set |
---|
comment:2 by , 16 years ago
comment:3 by , 16 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
comment:4 by , 16 years ago
I'm not going to worry about whether or not to make _default_manager
public here, since that isn't a well defined problem at the moment, so a "fix" isn't going to clearly correct or incorrect (working out whether access to that parameter is part of the problem). Normally, if you're referring to some other model you either know the model you're referring to, so can use the right manager, or it's a relation, in which case the manager choice is automatic. It's only real edge-cases that need to understand the concept of a default manager and won't know it's name (such as the admin) and they are a corner case in the application space. I've moved that to #10499 and leaving this ticket as being about interleaving new default managers.
The other problem is already possible to solve using class inheritance (mixins, since it's mixing in a new default manager to the default hierarchy). No new feature is required there. I'm about to commit some documentation to explain that pattern explicitly in the documentation.
comment:5 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Run out of time today. I'll commit this change tomorrow; I've got it done and ready to go.
comment:6 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Perhaps it is better to just make
objects
the (overrideable) default manager as suggested in http://groups.google.com/group/django-developers/browse_thread/thread/480fe23f12e55cf7 . I.e. the concept needs a little thought, care and love.