在django模型上改变孩子的类 [英] Change class of child on django models

查看:100
本文介绍了在django模型上改变孩子的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  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 

然后所有B的属性即使没有为类C定义也可用。
Altough 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)

这里是我的测试: p>

  class ABCTestCase(TestCase):
def test_changing_classes(self):
更改类
a = A()
self.assertIsInstance(a,A)
a.attrA ='培根'
self.assertEqual(a.attrA,'培根')
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 =无
a.save()
self.assertIsNotNone(a .id)

测试结果可以。



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


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()

Now, based on some decisions I wanted to transform that object b an instance of the C class but with the attrC attribute available. Is that possible?

解决方案

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.

这篇关于在django模型上改变孩子的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆