Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Migrieren mit ModelState und ProjectState unter Verwendung der Migrations-API in Django 3.0.3 nicht möglich

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.