Fix Django 1.5 support, tests pass again.
The reason polymorphic broke was because it couldn't find some managers anymore in the inheritance tree. Django 1.5 removes these and replaces them with an `AbstractManagerDescriptor`. This patch restores those objectsfix_request_path_info
parent
ca4067e279
commit
1f26302632
|
|
@ -16,6 +16,11 @@ from query import PolymorphicQuerySet
|
|||
# These are forbidden as field names (a descriptive exception is raised)
|
||||
POLYMORPHIC_SPECIAL_Q_KWORDS = ['instance_of', 'not_instance_of']
|
||||
|
||||
try:
|
||||
from django.db.models.manager import AbstractManagerDescriptor # Django 1.5
|
||||
except ImportError:
|
||||
AbstractManagerDescriptor = None
|
||||
|
||||
|
||||
###################################################################################
|
||||
### PolymorphicModel meta class
|
||||
|
|
@ -91,6 +96,7 @@ class PolymorphicModelBase(ModelBase):
|
|||
use correct mro, only use managers with _inherited==False (they are of no use),
|
||||
skip managers that are overwritten by the user with same-named class attributes (in attrs)
|
||||
"""
|
||||
#print "** ", self.__name__
|
||||
add_managers = []
|
||||
add_managers_keys = set()
|
||||
for base in self.__mro__[1:]:
|
||||
|
|
@ -102,9 +108,23 @@ class PolymorphicModelBase(ModelBase):
|
|||
for key, manager in base.__dict__.items():
|
||||
if type(manager) == models.manager.ManagerDescriptor:
|
||||
manager = manager.manager
|
||||
|
||||
if AbstractManagerDescriptor is not None:
|
||||
# Django 1.4 unconditionally assigned managers to a model. As of Django 1.5 however,
|
||||
# the abstract models don't get any managers, only a AbstractManagerDescriptor as substitute.
|
||||
# Pretend that the manager is still there, so all code works like it used to.
|
||||
if type(manager) == AbstractManagerDescriptor and base.__name__ == 'PolymorphicModel':
|
||||
model = manager.model
|
||||
if key == 'objects':
|
||||
manager = PolymorphicManager()
|
||||
manager.model = model
|
||||
elif key == 'base_objects':
|
||||
manager = models.Manager()
|
||||
manager.model = model
|
||||
|
||||
if not isinstance(manager, models.Manager):
|
||||
continue
|
||||
if key in ['_base_manager']:
|
||||
if key == '_base_manager':
|
||||
continue # let Django handle _base_manager
|
||||
if key in attrs:
|
||||
continue
|
||||
|
|
@ -112,7 +132,8 @@ class PolymorphicModelBase(ModelBase):
|
|||
continue # manager with that name already added, skip
|
||||
if manager._inherited:
|
||||
continue # inherited managers (on the bases) have no significance, they are just copies
|
||||
#print >>sys.stderr,'##',self.__name__, key
|
||||
#print '## {0} {1}'.format(self.__name__, key)
|
||||
|
||||
if isinstance(manager, PolymorphicManager): # validate any inherited polymorphic managers
|
||||
self.validate_model_manager(manager, self.__name__, key)
|
||||
add_managers.append((base.__name__, key, manager))
|
||||
|
|
@ -121,16 +142,18 @@ class PolymorphicModelBase(ModelBase):
|
|||
|
||||
@classmethod
|
||||
def get_first_user_defined_manager(self):
|
||||
# See if there is a manager attribute directly stored at this inheritance level.
|
||||
mgr_list = []
|
||||
for key, val in self.__dict__.items():
|
||||
item = getattr(self, key)
|
||||
if not isinstance(item, models.Manager): continue
|
||||
mgr_list.append((item.creation_counter, key, item))
|
||||
|
||||
# if there are user defined managers, use first one as _default_manager
|
||||
if mgr_list:
|
||||
_, manager_name, manager = sorted(mgr_list)[0]
|
||||
#sys.stderr.write( '\n# first user defined manager for model "{model}":\n# "{mgrname}": {mgr}\n# manager model: {mgrmodel}\n\n'
|
||||
# .format( model=model_name, mgrname=manager_name, mgr=manager, mgrmodel=manager.model ) )
|
||||
# .format( model=self.__name__, mgrname=manager_name, mgr=manager, mgrmodel=manager.model ) )
|
||||
return manager
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ class PolymorphicModel(models.Model):
|
|||
# some applications want to know the name of the fields that are added to its models
|
||||
polymorphic_internal_model_fields = ['polymorphic_ctype']
|
||||
|
||||
# Note that Django 1.5 removes these managers because the model is abstract.
|
||||
# They are pretended to be there by the metaclass in PolymorphicModelBase.get_inherited_managers()
|
||||
objects = PolymorphicManager()
|
||||
base_objects = models.Manager()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue