diff --git a/django/db/models/manager.py b/django/db/models/manager.py index e1bbf6ebc5..522a8a2306 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -13,7 +13,7 @@ def ensure_default_manager(sender, **kwargs): _default_manager if it's not a subclass of Manager). """ cls = sender - if cls._meta.abstract: + if cls._meta.abstract or cls._meta.swapped: return if not getattr(cls, '_default_manager', None): # Create the default manager, if needed. @@ -42,6 +42,7 @@ def ensure_default_manager(sender, **kwargs): signals.class_prepared.connect(ensure_default_manager) + class Manager(object): # Tracks each time a Manager instance is created. Used to retain order. creation_counter = 0 @@ -56,7 +57,9 @@ class Manager(object): def contribute_to_class(self, model, name): # TODO: Use weakref because of possible memory leak / circular reference. self.model = model - setattr(model, name, ManagerDescriptor(self)) + # Only contribute the manager if the model is concrete + if not model._meta.abstract and not model._meta.swapped: + setattr(model, name, ManagerDescriptor(self)) if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter: model._default_manager = self if model._meta.abstract or (self._inherited and not self.model._meta.proxy): @@ -208,6 +211,7 @@ class Manager(object): def raw(self, raw_query, params=None, *args, **kwargs): return RawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs) + class ManagerDescriptor(object): # This class ensures managers aren't accessible via model instances. # For example, Poll.objects works, but poll_obj.objects raises AttributeError. @@ -219,6 +223,7 @@ class ManagerDescriptor(object): raise AttributeError("Manager isn't accessible via %s instances" % type.__name__) return self.manager + class EmptyManager(Manager): def get_query_set(self): return self.get_empty_query_set() diff --git a/django/db/models/options.py b/django/db/models/options.py index 446aa54303..d2de96ea5c 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -222,10 +222,15 @@ class Options(object): def _swapped(self): """ - Has this model been swapped out for another? + Has this model been swapped out for another? If so, return the model + name of the replacement; otherwise, return None. """ - model_label = '%s.%s' % (self.app_label, self.object_name) - return self.swappable and getattr(settings, self.swappable, None) not in (None, model_label) + if self.swappable: + model_label = '%s.%s' % (self.app_label, self.object_name) + swapped_for = getattr(settings, self.swappable, None) + if swapped_for not in (None, model_label): + return swapped_for + return None swapped = property(_swapped) def _fields(self):