sql >> Databasteknik >  >> RDS >> Mysql

Det går inte att migrera med ModelState och ProjectState med hjälp av migrations API i Django 3.0.3

För att börja behöver du att använda modellens metaklass , dvs. ModelBase kod> , och inte typ :

from django.db.models.base import ModelBase

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

När du använder rätt metaklass , kommer du sannolikt att få en myriad av fel, eftersom du använder många klassattribut som ModelBase ställer in internt och förväntar sig inte att du ska ställa in dig själv.

Istället för att dumpa alla attribut som din modell har, bör du bara ställa in de attribut som ModelBase förväntar sig att vara inställd på en traditionell modell, som inkluderar:

  • __modul__ och __qualname__
  • modellfält
  • anpassade hanterare eller frågeuppsättningar
  • modellmetoder
  • modell Meta

Allt annat bör utelämnas.

Så till exempel, om du har en modell som ser ut så här, i modulen 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'

Den dynamiska versionen av dessa modeller måste se ut så här:

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

Jag förstår inte syftet med din migreringskod, så jag antar att det var ett hack i ett försök att få de dynamiska modellerna att fungera, vilket innebär att du förmodligen kan slänga ut den helt och hållet och använda den inbyggda migreringsladdaren, dvs:

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

Om du inte är bekant med python metaklasser , jag skulle rekommendera att läsa upp dem, eftersom det är en förutsättning för att förstå min kod.




  1. Två olika leverantörer på samma konfigurationsfil

  2. Ställer in klasssökvägen för JAR-filer

  3. WooCommerce-produkter som visar meddelandet "Ej i lager" när de inte är slut i lager

  4. Android - JSON mySQL-fråga ger NetworkOnMainThreadException