From 7e584632b85c23c57cfb526c1ea6e9a9bdb86cf9 Mon Sep 17 00:00:00 2001 From: Bert Constantin Date: Thu, 18 Feb 2010 17:13:05 +0100 Subject: [PATCH] fix unnecessary field-name/model-name conflicts (i.e. field_name == model_name.lower() ) => __init__ + __getattribute__ now handle only the Django inheritance references that are needed ('modela_ptr', 'modelc' etc.), avoiding unnecessary conflicts with field names. --- .gitignore | 1 + polymorphic/polymorphic.py | 31 ++++++++++++++++++------------- polymorphic/tests.py | 8 ++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index eb203ac..ae35267 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .project .pydevproject .settings +nbproject tmp libraries-local diff --git a/polymorphic/polymorphic.py b/polymorphic/polymorphic.py index 7306f67..d72f93c 100644 --- a/polymorphic/polymorphic.py +++ b/polymorphic/polymorphic.py @@ -678,11 +678,11 @@ class PolymorphicModel(models.Model): def __getattribute__(self, name): if name != '__class__': #if name.endswith('_ptr_cache'): # unclear if this should be handled as well - if name.endswith('_ptr'): name = name[:-4] model = self.__class__.sub_and_superclass_dict.get(name, None) - if model: + if model: id = super(PolymorphicModel, self).__getattribute__('id') attr = model.base_objects.get(id=id) + #print '---',self.__class__.__name__,name return attr return super(PolymorphicModel, self).__getattribute__(name) @@ -690,23 +690,28 @@ class PolymorphicModel(models.Model): # containing all model attribute names we need to intercept # (do this once here instead of in __getattribute__ every time) def __init__(self, *args, **kwargs): - if not getattr(self.__class__, 'sub_and_superclass_dict', None): + if not self.__class__.__dict__.get('sub_and_superclass_dict', None): + + def add_if_regular_sub_or_super_class(model, as_ptr, result): + if ( issubclass(model, models.Model) and model != models.Model + and model != self.__class__ and model != PolymorphicModel): + name = model.__name__.lower() + if as_ptr: name+='_ptr' + result[name] = model def add_all_base_models(model, result): - if issubclass(model, models.Model) and model != models.Model: - result[model.__name__.lower()] = model + add_if_regular_sub_or_super_class(model, True, result) for b in model.__bases__: add_all_base_models(b, result) - def add_all_sub_models(model, result): - if issubclass(model, models.Model) and model != models.Model: - result[model.__name__.lower()] = model + def add_sub_models(model, result): for b in model.__subclasses__(): - add_all_sub_models(b, result) - + add_if_regular_sub_or_super_class(b, False, result) + result = {} - add_all_base_models(self.__class__, result) - add_all_sub_models(self.__class__, result) + add_all_base_models(self.__class__,result) + add_sub_models(self.__class__,result) + #print '##',self.__class__.__name__,' - ',result self.__class__.sub_and_superclass_dict = result - + super(PolymorphicModel, self).__init__(*args, **kwargs) def __repr__(self): diff --git a/polymorphic/tests.py b/polymorphic/tests.py index 4b9f7c0..530db45 100644 --- a/polymorphic/tests.py +++ b/polymorphic/tests.py @@ -99,6 +99,9 @@ class BlogA_Entry(ShowFieldsAndTypes, PolymorphicModel): blog = models.ForeignKey(BlogA) text = models.CharField(max_length=10) +class ModelFieldNameTest(PolymorphicModel): + modelfieldnametest = models.CharField(max_length=10) + # test bad field name #class TestBadFieldModel(PolymorphicModel): # instance_of = models.CharField(max_length=10) @@ -303,12 +306,17 @@ __test__ = {"doctest": """ >>> type(MROBase2._default_manager) +### fixed issue in PolymorphicModel.__getattribute__: field name same as model name +>>> ModelFieldNameTest.objects.create(modelfieldnametest='1') + + ### Django model inheritance diamond problem, fails for Django 1.1 #>>> o=DiamondXY.objects.create(field_b='b', field_x='x', field_y='y') #>>> print 'DiamondXY fields 1: field_b "%s", field_x "%s", field_y "%s"' % (o.field_b, o.field_x, o.field_y) #DiamondXY fields 1: field_b "a", field_x "x", field_y "y" + >>> settings.DEBUG=False """}