Disable the old _default_manager and _copy_to_model() fiddling.
This no longer works on Django 1.10, which has a new way to find the default managerfix_request_path_info
parent
3172b41cbb
commit
a5e348ffb9
|
|
@ -71,24 +71,25 @@ class PolymorphicModelBase(ModelBase):
|
||||||
self.validate_model_fields(new_class)
|
self.validate_model_fields(new_class)
|
||||||
|
|
||||||
# create list of all managers to be inherited from the base classes
|
# create list of all managers to be inherited from the base classes
|
||||||
inherited_managers = new_class.get_inherited_managers(attrs)
|
if django.VERSION < (1, 10):
|
||||||
|
inherited_managers = new_class.get_inherited_managers(attrs)
|
||||||
|
|
||||||
# add the managers to the new model
|
# add the managers to the new model
|
||||||
for source_name, mgr_name, manager in inherited_managers:
|
for source_name, mgr_name, manager in inherited_managers:
|
||||||
# print '** add inherited manager from model %s, manager %s, %s' % (source_name, mgr_name, manager.__class__.__name__)
|
# print '** add inherited manager from model %s, manager %s, %s' % (source_name, mgr_name, manager.__class__.__name__)
|
||||||
new_manager = manager._copy_to_model(new_class)
|
new_manager = manager._copy_to_model(new_class)
|
||||||
if mgr_name == '_default_manager':
|
if mgr_name == '_default_manager':
|
||||||
new_class._default_manager = new_manager
|
new_class._default_manager = new_manager
|
||||||
else:
|
else:
|
||||||
new_class.add_to_class(mgr_name, new_manager)
|
new_class.add_to_class(mgr_name, new_manager)
|
||||||
|
|
||||||
# get first user defined manager; if there is one, make it the _default_manager
|
# get first user defined manager; if there is one, make it the _default_manager
|
||||||
# this value is used by the related objects, restoring access to custom queryset methods on related objects.
|
# this value is used by the related objects, restoring access to custom queryset methods on related objects.
|
||||||
user_manager = self.get_first_user_defined_manager(new_class)
|
user_manager = self.get_first_user_defined_manager(new_class)
|
||||||
if user_manager:
|
if user_manager:
|
||||||
# print '## add default manager', type(def_mgr)
|
# print '## add default manager', type(def_mgr)
|
||||||
new_class._default_manager = user_manager._copy_to_model(new_class)
|
new_class._default_manager = user_manager._copy_to_model(new_class)
|
||||||
new_class._default_manager._inherited = False # the default mgr was defined by the user, not inherited
|
new_class._default_manager._inherited = False # the default mgr was defined by the user, not inherited
|
||||||
|
|
||||||
# validate resulting default manager
|
# validate resulting default manager
|
||||||
self.validate_model_manager(new_class._default_manager, model_name, '_default_manager')
|
self.validate_model_manager(new_class._default_manager, model_name, '_default_manager')
|
||||||
|
|
@ -105,80 +106,81 @@ class PolymorphicModelBase(ModelBase):
|
||||||
|
|
||||||
return new_class
|
return new_class
|
||||||
|
|
||||||
def get_inherited_managers(self, attrs):
|
if django.VERSION < (1, 10):
|
||||||
"""
|
def get_inherited_managers(self, attrs):
|
||||||
Return list of all managers to be inherited/propagated from the base classes;
|
"""
|
||||||
use correct mro, only use managers with _inherited==False (they are of no use),
|
Return list of all managers to be inherited/propagated from the base classes;
|
||||||
skip managers that are overwritten by the user with same-named class attributes (in attrs)
|
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 = []
|
# print "** ", self.__name__
|
||||||
add_managers_keys = set()
|
add_managers = []
|
||||||
for base in self.__mro__[1:]:
|
add_managers_keys = set()
|
||||||
if not issubclass(base, models.Model):
|
for base in self.__mro__[1:]:
|
||||||
continue
|
if not issubclass(base, models.Model):
|
||||||
if not getattr(base, 'polymorphic_model_marker', None):
|
|
||||||
continue # leave managers of non-polym. models alone
|
|
||||||
|
|
||||||
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
|
continue
|
||||||
if key == '_base_manager':
|
if not getattr(base, 'polymorphic_model_marker', None):
|
||||||
continue # let Django handle _base_manager
|
continue # leave managers of non-polym. models alone
|
||||||
if key in attrs:
|
|
||||||
|
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 == '_base_manager':
|
||||||
|
continue # let Django handle _base_manager
|
||||||
|
if key in attrs:
|
||||||
|
continue
|
||||||
|
if key in add_managers_keys:
|
||||||
|
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 '## {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))
|
||||||
|
add_managers_keys.add(key)
|
||||||
|
|
||||||
|
# The ordering in the base.__dict__ may randomly change depending on which method is added.
|
||||||
|
# Make sure base_objects is on top, and 'objects' and '_default_manager' follow afterwards.
|
||||||
|
# This makes sure that the _base_manager is also assigned properly.
|
||||||
|
add_managers = sorted(add_managers, key=lambda item: (item[1].startswith('_'), item[1]))
|
||||||
|
return add_managers
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_first_user_defined_manager(mcs, new_class):
|
||||||
|
# See if there is a manager attribute directly stored at this inheritance level.
|
||||||
|
mgr_list = []
|
||||||
|
for key, val in new_class.__dict__.items():
|
||||||
|
if isinstance(val, ManagerDescriptor):
|
||||||
|
val = val.manager
|
||||||
|
if not isinstance(val, PolymorphicManager):
|
||||||
continue
|
continue
|
||||||
if key in add_managers_keys:
|
|
||||||
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 '## {0} {1}'.format(self.__name__, key)
|
|
||||||
|
|
||||||
if isinstance(manager, PolymorphicManager): # validate any inherited polymorphic managers
|
mgr_list.append((val.creation_counter, key, val))
|
||||||
self.validate_model_manager(manager, self.__name__, key)
|
|
||||||
add_managers.append((base.__name__, key, manager))
|
|
||||||
add_managers_keys.add(key)
|
|
||||||
|
|
||||||
# The ordering in the base.__dict__ may randomly change depending on which method is added.
|
# if there are user defined managers, use first one as _default_manager
|
||||||
# Make sure base_objects is on top, and 'objects' and '_default_manager' follow afterwards.
|
if mgr_list:
|
||||||
# This makes sure that the _base_manager is also assigned properly.
|
_, manager_name, manager = sorted(mgr_list)[0]
|
||||||
add_managers = sorted(add_managers, key=lambda item: (item[1].startswith('_'), item[1]))
|
# sys.stderr.write( '\n# first user defined manager for model "{model}":\n# "{mgrname}": {mgr}\n# manager model: {mgrmodel}\n\n'
|
||||||
return add_managers
|
# .format( model=self.__name__, mgrname=manager_name, mgr=manager, mgrmodel=manager.model ) )
|
||||||
|
return manager
|
||||||
@classmethod
|
return None
|
||||||
def get_first_user_defined_manager(mcs, new_class):
|
|
||||||
# See if there is a manager attribute directly stored at this inheritance level.
|
|
||||||
mgr_list = []
|
|
||||||
for key, val in new_class.__dict__.items():
|
|
||||||
if isinstance(val, ManagerDescriptor):
|
|
||||||
val = val.manager
|
|
||||||
if not isinstance(val, PolymorphicManager):
|
|
||||||
continue
|
|
||||||
|
|
||||||
mgr_list.append((val.creation_counter, key, val))
|
|
||||||
|
|
||||||
# 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=self.__name__, mgrname=manager_name, mgr=manager, mgrmodel=manager.model ) )
|
|
||||||
return manager
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def call_superclass_new_method(self, model_name, bases, attrs):
|
def call_superclass_new_method(self, model_name, bases, attrs):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue