summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-03-20 16:10:51 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-03-20 16:10:51 +0000
commite2dfad15f14f4da61ec7bcfc5cab2b083fd7ec63 (patch)
treed4f0d368153a675662ac3ca9446228ee46762d3e
parentcdeebb33f57dc2e5f4d0f60fd7f4a7fee6b02cb7 (diff)
queyrset-refactor: Allow default managers to be inherited from an abstract base
class, unless the child class defines its own manager (i.e. child has first chance to define the default). All managers were already inherited. This just changes how the default is set in the case when the child defines no manager and an abstract parent does. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7339 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/base.py14
-rw-r--r--django/db/models/manager.py17
2 files changed, 24 insertions, 7 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 0d06ca5727..02c5398fb1 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -3,8 +3,8 @@ import sys
import os
from itertools import izip
-import django.db.models.manipulators
-import django.db.models.manager
+import django.db.models.manipulators # Imported to register signal handler.
+import django.db.models.manager # Ditto.
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
@@ -59,9 +59,11 @@ class ModelBase(type):
if not hasattr(meta, 'get_latest_by'):
new_class._meta.get_latest_by = base_meta.get_latest_by
- if getattr(new_class, '_default_manager', None) is not None:
- # We have a parent who set the default manager. We need to override
- # this.
+ old_default_mgr = None
+ if getattr(new_class, '_default_manager', None):
+ # We have a parent who set the default manager.
+ if new_class._default_manager.model._meta.abstract:
+ old_default_mgr = new_class._default_manager
new_class._default_manager = None
if getattr(new_class._meta, 'app_label', None) is None:
# Figure out the app_label by looking one level up.
@@ -113,6 +115,8 @@ class ModelBase(type):
new_class.Meta = attr_meta
return new_class
+ if old_default_mgr and not new_class._default_manager:
+ new_class._default_manager = old_default_mgr._copy_to_model(new_class)
new_class._prepare()
register_models(new_class._meta.app_label, new_class)
diff --git a/django/db/models/manager.py b/django/db/models/manager.py
index 3a2efe84a8..1e2cd58850 100644
--- a/django/db/models/manager.py
+++ b/django/db/models/manager.py
@@ -1,3 +1,5 @@
+import copy
+
from django.db.models.query import QuerySet, EmptyQuerySet, insert_query
from django.dispatch import dispatcher
from django.db.models import signals
@@ -5,7 +7,7 @@ from django.db.models.fields import FieldDoesNotExist
def ensure_default_manager(sender):
cls = sender
- if not hasattr(cls, '_default_manager') or cls._default_manager is None:
+ if not getattr(cls, '_default_manager', None) and not cls._meta.abstract:
# Create the default manager, if needed.
try:
cls._meta.get_field('objects')
@@ -31,9 +33,20 @@ class Manager(object):
# TODO: Use weakref because of possible memory leak / circular reference.
self.model = model
setattr(model, name, ManagerDescriptor(self))
- if not hasattr(model, '_default_manager') or model._default_manager is None or self.creation_counter < model._default_manager.creation_counter:
+ if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
model._default_manager = self
+ def _copy_to_model(self, model):
+ """
+ Makes a copy of the manager and assigns it to 'model', which should be
+ a child of the existing model (used when inheriting a manager from an
+ abstract base class).
+ """
+ assert issubclass(model, self.model)
+ mgr = copy.copy(self)
+ mgr.model = model
+ return mgr
+
#######################
# PROXIES TO QUERYSET #
#######################