简体   繁体   English

在Django模型上更改子类

[英]Change class of child on django models

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 = models.CharField()

And then I create a instnace of B: 然后创建一个B的实例:

b = B()

Now, based on some decisions I wanted to transform that object b an instance of the C class but with the attrC attribute available. 现在,基于一些决策,我想将该对象转换为C类的实例,但具有attrC属性。 Is that possible? 那可能吗?

In python you can change class of an object like that: 在python中,您可以像这样更改对象的类:

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. 这样,即使未为类C定义B的所有属性,它们也仍然可用。虽然b现在是类C的实例,但它没有C的属性。 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. 在将对象保存到数据库(或调用Model类的其他方法)之前,您必须添加类C的所有其余属性。为证明其有效,我创建了一个简单的应用程序。 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. 比较安全的方法是为从B到C或从C到B转换的每个类定义方法。

b = C() would make the local variable b an instance of the C class. b = C()将使局部变量b成为C类的实例。 Not sure why you would want to do this though. 不知道为什么要这么做。 Can you post more of your code? 您可以发布更多代码吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM