Per iniziare, è necessario utilizzare la metaclasse del modello , cioè. ModelBase
, e non type
:
from django.db.models.base import ModelBase
model_definition = ModelBase(
model_item.table_name,
bases,
model_config
)
Dopo aver utilizzato la corretta metaclass , probabilmente riceverai una miriade di errori, poiché stai utilizzando molti attributi di classe che ModelBase
imposta internamente e non si aspetta che tu configuri te stesso.
Invece di scaricare tutti gli attributi del tuo modello, dovresti impostare solo gli attributi che ModelBase
prevede di essere impostato su un modello tradizionale, che include:
__module__
e__qualname__
- campi modello
- gestori personalizzati o set di query
- metodi modello
- modello
Meta
Tutto il resto dovrebbe essere omesso.
Ad esempio, se hai un modello simile a questo, nel modulo 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'
La versione dinamica di questi modelli deve essere simile a questa:
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'}),
})
Non capisco lo scopo del tuo codice di migrazione, quindi presumo che sia stato un hack nel tentativo di far funzionare i modelli dinamici, il che significa che probabilmente puoi eliminarlo del tutto e utilizzare il caricatore di migrazione integrato, ovvero:
python3 manage.py makemigrations myapp && python3 manage.py migrate myapp
Non hai familiarità con python metaclasses
, ti consiglio di leggerli, poiché è un prerequisito per comprendere il mio codice.