簡體   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