Zu Beginn benötigen Sie um die Modell-Metaklasse zu verwenden , dh. ModelBase
, und nicht type
:
from django.db.models.base import ModelBase
model_definition = ModelBase(
model_item.table_name,
bases,
model_config
)
Sobald Sie die richtige Metaklasse verwenden , erhalten Sie wahrscheinlich unzählige Fehler, da Sie viele Klassenattribute verwenden, die ModelBase
setzt intern und erwartet nicht, dass Sie sich selbst setzen.
Anstatt alle Attribute Ihres Modells auszugeben, sollten Sie nur die Attribute festlegen, die ModelBase
erwartet, auf ein traditionelles Modell gesetzt zu werden, das Folgendes beinhaltet:
__module__
und__qualname__
- Modellfelder
- benutzerdefinierte Manager oder Abfragesätze
- Modellmethoden
- Modell
Meta
Alles andere sollte weggelassen werden.
Wenn Sie also beispielsweise Modelle haben, die so aussehen, im Modul myapp.models
:
class Parent(models.Model):
name = models.CharField(max_length=45)
class Child(models.Model):
name = models.CharField(max_length=45)
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
class ModelWithMeta(models.Model):
class Meta:
db_table = 'some_table'
Die dynamische Version dieser Modelle muss wie folgt aussehen:
from django.db import models
from django.db.models.base import ModelBase
bases = (models.Model,)
Parent = ModelBase('Parent', bases, {
'__module__': 'myapp.models',
'__qualname__': 'Parent',
'name': models.CharField(max_length=45),
})
Child = ModelBase('Child', bases, {
'__module__': 'myapp.models',
'__qualname__': 'Child',
'name': models.CharField(max_length=45),
'parent': models.ForeignKey('myapp.Parent', on_delete=models.CASCADE),
})
ModelWithMeta = ModelBase('ModelWithMeta', bases, {
'__module__': 'myapp.models',
'__qualname__': 'ModelWithMeta',
'Meta': type('Meta', (), {'db_table': 'some_table'}),
})
Ich verstehe den Zweck Ihres Migrationscodes nicht, daher gehe ich davon aus, dass es sich um einen Hack handelte, um die dynamischen Modelle zum Laufen zu bringen, was bedeutet, dass Sie ihn wahrscheinlich ganz wegwerfen und den integrierten Migrationslader verwenden können, dh:
python3 manage.py makemigrations myapp && python3 manage.py migrate myapp
Wenn Sie mit Python-metaclasses
, ich würde empfehlen, sie zu lesen, da dies eine Voraussetzung ist, um meinen Code zu verstehen.