Change class of child on django models

后端 未结 2 475
感动是毒
感动是毒 2020-12-12 04:38

Lets say I have classes in the form:

class A(models.Model):
   attrA = models.CharField()
class B(A):
   attrB = models.CharField()
class C(A):
   attrC = m         


        
相关标签:
2条回答
  • 2020-12-12 04:46

    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.

    0 讨论(0)
  • 2020-12-12 04:51

    b = C() would make the local variable b an instance of the C class. Not sure why you would want to do this though. Can you post more of your code?

    0 讨论(0)
提交回复
热议问题