Ändern Sie die Klasse des Kindes auf Django-Modelle

Lets sagen, ich habe Klassen in der Form:

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

Und dann schaffe ich eine Instanz von B:

 b = B() 

Nun, auf der Grundlage einiger Entscheidungen wollte ich dieses Objekt b eine Instanz der C-Klasse umwandeln, aber mit dem attrC-Attribut zur Verfügung. Ist das möglich?

2 Solutions collect form web for “Ändern Sie die Klasse des Kindes auf Django-Modelle”

In python können Sie die Klasse eines Objekts wie folgt ändern:

 b.__class__=C 

Dann sind alle B-Attribute verfügbar, auch wenn sie nicht für Klasse C definiert sind. Obwohl b jetzt Instanz der Klasse C ist, hat es keine C-Attribute. Bevor Sie das Objekt in die Datenbank speichern (oder andere Methoden der Modellklasse aufrufen), müssen Sie alle übrigen Attribute der Klasse C hinzufügen. Um zu beweisen, dass es funktioniert, habe ich eine einfache App erstellt. Hier sind meine Modelle:

 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) 

Und hier sind meine 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) 

Ergebnis des Tests ist OK.

Sicherer Ansatz ist es, eine Methode für jede Klasse zu definieren, die von B nach C oder von C nach B umwandelt.

B = C () würde die lokale Variable b eine Instanz der C-Klasse machen. Nicht sicher, warum du das auch machen möchtest. Kannst du mehr von deinem Code posten?

  • Wie werden Argumente an eine Funktion über __getattr__ übergeben
  • Python parent class 'wrapping' Kind-Klasse Methoden
  • Cast Basisklasse zu abgeleiteten Klasse Python (oder mehr pythonischen Weg der Erweiterung Klassen)
  • Rufen Sie die Methode von der Spitzenklasse in der Hierarchie an, anstatt zu überschreiben
  • Mit einer Klasse '__new__ Methode als Factory: __init__ wird zweimal aufgerufen
  • Django Multi-Table-Vererbung, wie zu wissen, welche ist die Kind-Klasse eines Modells?
  • Warum werden nicht Pythons Superklasse __init__ Methoden automatisch aufgerufen?
  • Single Table Vererbung in Django
  • Python vererbbare Funktionen
  • Kann die Methode des Elternteils im Listenverständnis im Initialisierer des Kindes nicht aufrufen, aber explizite Schleife funktioniert
  • Sind die Accessoren in Python jemals gerechtfertigt?
  • Python ist die beste Programmiersprache der Welt.