Ensure swapped models can't be queried.
This commit is contained in:
parent
57ac6e3d32
commit
5d7bb22e8d
|
@ -13,7 +13,7 @@ def ensure_default_manager(sender, **kwargs):
|
||||||
_default_manager if it's not a subclass of Manager).
|
_default_manager if it's not a subclass of Manager).
|
||||||
"""
|
"""
|
||||||
cls = sender
|
cls = sender
|
||||||
if cls._meta.abstract:
|
if cls._meta.abstract or cls._meta.swapped:
|
||||||
return
|
return
|
||||||
if not getattr(cls, '_default_manager', None):
|
if not getattr(cls, '_default_manager', None):
|
||||||
# Create the default manager, if needed.
|
# Create the default manager, if needed.
|
||||||
|
@ -42,6 +42,7 @@ def ensure_default_manager(sender, **kwargs):
|
||||||
|
|
||||||
signals.class_prepared.connect(ensure_default_manager)
|
signals.class_prepared.connect(ensure_default_manager)
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
# Tracks each time a Manager instance is created. Used to retain order.
|
# Tracks each time a Manager instance is created. Used to retain order.
|
||||||
creation_counter = 0
|
creation_counter = 0
|
||||||
|
@ -56,7 +57,9 @@ class Manager(object):
|
||||||
def contribute_to_class(self, model, name):
|
def contribute_to_class(self, model, name):
|
||||||
# TODO: Use weakref because of possible memory leak / circular reference.
|
# TODO: Use weakref because of possible memory leak / circular reference.
|
||||||
self.model = model
|
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:
|
if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
|
||||||
model._default_manager = self
|
model._default_manager = self
|
||||||
if model._meta.abstract or (self._inherited and not self.model._meta.proxy):
|
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):
|
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)
|
return RawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ManagerDescriptor(object):
|
class ManagerDescriptor(object):
|
||||||
# This class ensures managers aren't accessible via model instances.
|
# This class ensures managers aren't accessible via model instances.
|
||||||
# For example, Poll.objects works, but poll_obj.objects raises AttributeError.
|
# 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__)
|
raise AttributeError("Manager isn't accessible via %s instances" % type.__name__)
|
||||||
return self.manager
|
return self.manager
|
||||||
|
|
||||||
|
|
||||||
class EmptyManager(Manager):
|
class EmptyManager(Manager):
|
||||||
def get_query_set(self):
|
def get_query_set(self):
|
||||||
return self.get_empty_query_set()
|
return self.get_empty_query_set()
|
||||||
|
|
|
@ -222,10 +222,15 @@ class Options(object):
|
||||||
|
|
||||||
def _swapped(self):
|
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)
|
if self.swappable:
|
||||||
return self.swappable and getattr(settings, self.swappable, None) not in (None, model_label)
|
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)
|
swapped = property(_swapped)
|
||||||
|
|
||||||
def _fields(self):
|
def _fields(self):
|
||||||
|
|
Loading…
Reference in New Issue