In python you can change class of an object like that:
b.__class__=C
Then all of B's attributes are available even when they are not defined for class C.
Altough b is now instance of the class C it has no C's attributes.
Before saving the object to database (or calling other methods of Model class) you have to add all remaining attributes of the class C.
To prove it works I created a simple app. Here are my models:
class A(models.Model):
attrA = models.CharField(max_length=128)
class Meta:
abstract=True
class B(A):
attrB = models.CharField(max_length=128)
class C(A):
attrC = models.CharField(max_length=128)
And here are my tests:
class ABCTestCase(TestCase):
def test_changing_classes(self):
"""Changing classes"""
a = A()
self.assertIsInstance(a, A)
a.attrA='bacon'
self.assertEqual(a.attrA, 'bacon')
a.__class__=B
self.assertIsInstance(a, B)
self.assertEqual(a.attrA, 'bacon')
a.attrB='spam'
self.assertEqual(a.attrA, 'bacon')
self.assertEqual(a.attrB, 'spam')
a.__class__=C
self.assertIsInstance(a, C)
self.assertIsInstance(a, A)
self.assertNotIsInstance(a, B)
a.attrC='egg'
self.assertEqual(a.attrA, 'bacon')
self.assertEqual(a.attrB, 'spam')
self.assertEqual(a.attrC, 'egg')
a.id=None
a.save()
self.assertIsNotNone(a.id)
Result of the test is OK.
Safer approach is to define method for each class which convert from B to C or from C to B.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…