Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ensure swapped models can't be queried.

  • Loading branch information...
commit 5d7bb22e8d913b51aba1c3360e7af8b01b6c0ab6 1 parent 57ac6e3
@freakboy3742 freakboy3742 authored
Showing with 16 additions and 6 deletions.
  1. +7 −2 django/db/models/manager.py
  2. +9 −4 django/db/models/options.py
View
9 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 @@ def __init__(self):
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 @@ def _update(self, values, **kwargs):
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 @@ def __get__(self, instance, type=None):
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()
View
13 django/db/models/options.py
@@ -222,10 +222,15 @@ def verbose_name_raw(self):
def _swapped(self):
"""
- Has this model been swapped out for another?
- """
- model_label = '%s.%s' % (self.app_label, self.object_name)
- return self.swappable and getattr(settings, self.swappable, None) not in (None, model_label)
+ Has this model been swapped out for another? If so, return the model
+ name of the replacement; otherwise, return None.
+ """
+ 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):
Please sign in to comment.
Something went wrong with that request. Please try again.