sql >> Base de Datos >  >> RDS >> Mysql

No se puede migrar usando ModelState y ProjectState usando la API de migraciones en Django 3.0.3

Para empezar, necesitas estar usando la metaclase modelo , es decir. ModelBase , y no type :

from django.db.models.base import ModelBase

model_definition = ModelBase(
    model_item.table_name,
    bases,
    model_config
)

Una vez que utilice la metaclase adecuada , es probable que reciba una gran cantidad de errores, ya que está utilizando muchos atributos de clase que ModelBase establece internamente y no espera que usted mismo lo establezca.

En lugar de volcar todos los atributos que tiene su modelo, solo debe establecer los atributos que ModelBase espera establecerse en un modelo tradicional, que incluye:

  • __module__ y __qualname__
  • campos modelo
  • gestores personalizados o conjuntos de consultas
  • métodos modelo
  • modelo Meta

Todo lo demás debe omitirse.

Entonces, por ejemplo, si tiene modelos que se ven así, en el módulo 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 versión dinámica de estos modelos debe verse así:

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'}),
})

No entiendo el propósito de su código de migración, por lo que asumiré que fue un intento de piratear para que los modelos dinámicos funcionen, lo que significa que probablemente pueda descartarlo por completo y usar el cargador de migración incorporado, es decir:

python3 manage.py makemigrations myapp && python3 manage.py migrate myapp

Si no está familiarizado con Python metaclasses , recomendaría leer sobre ellos, ya que es un requisito previo para entender mi código.