繁体   English   中英

在Django模型上更改子类

[英]Change class of child on django models

可以说我有以下形式的课程:

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

然后创建一个B的实例:

b = B()

现在,基于一些决策,我想将该对象转换为C类的实例,但具有attrC属性。 那可能吗?

在python中,您可以像这样更改对象的类:

b.__class__=C

这样,即使未为类C定义B的所有属性,它们也仍然可用。虽然b现在是类C的实例,但它没有C的属性。 在将对象保存到数据库(或调用Model类的其他方法)之前,您必须添加类C的所有其余属性。为证明其有效,我创建了一个简单的应用程序。 这是我的模型:

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)

这是我的测试:

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)

测试结果正常。

比较安全的方法是为从B到C或从C到B转换的每个类定义方法。

b = C()将使局部变量b成为C类的实例。 不知道为什么要这么做。 您可以发布更多代码吗?

暂无
暂无

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

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