Estou planejando renomear vários modelos em um projeto existente do Django, onde existem muitos outros modelos que têm relacionamentos de chave estrangeira com os modelos que gostaria de renomear. Estou bastante certo de que isso exigirá várias migrações, mas não tenho certeza do procedimento exato.
Digamos que eu comece com os seguintes modelos em um aplicativo Django chamado myapp
:
class Foo(models.Model):
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
foo = models.ForeignKey(Foo)
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ForeignKey(Foo)
is_ridonkulous = models.BooleanField()
Quero renomear o Foo
modelo porque o nome realmente não faz sentido e está causando confusão no código, e Bar
tornaria um nome muito mais claro.
Pelo que li na documentação de desenvolvimento do Django, estou assumindo a seguinte estratégia de migração:
Passo 1
Modificar models.py
:
class Bar(models.Model): # <-- changed model name
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
foo = models.ForeignKey(Bar) # <-- changed relation, but not field name
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
foo = models.ForeignKey(Bar) # <-- changed relation, but not field name
is_ridonkulous = models.BooleanField()
Observe que o AnotherModel
nome do campo para foo
não muda, mas a relação é atualizada para o Bar
modelo. Meu raciocínio é que eu não deveria mudar muito de uma só vez e que se eu alterasse esse nome de campo, bar
correria o risco de perder os dados nessa coluna.
Passo 2
Crie uma migração vazia:
python manage.py makemigrations --empty myapp
etapa 3
Edite a Migration
classe no arquivo de migração criado na etapa 2 para adicionar a RenameModel
operação à lista de operações:
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RenameModel('Foo', 'Bar')
]
Passo 4
Aplique a migração:
python manage.py migrate
Etapa 5
Edite os nomes dos campos relacionados em models.py
:
class Bar(models.Model):
name = models.CharField(unique=True, max_length=32)
description = models.TextField(null=True, blank=True)
class AnotherModel(models.Model):
bar = models.ForeignKey(Bar) # <-- changed field name
is_awesome = models.BooleanField()
class YetAnotherModel(models.Model):
bar = models.ForeignKey(Bar) # <-- changed field name
is_ridonkulous = models.BooleanField()
Etapa 6
Crie outra migração vazia:
python manage.py makemigrations --empty myapp
Etapa 7
Edite a Migration
classe no arquivo de migração criado na etapa 6 para adicionar as RenameField
operações de qualquer nome de campo relacionado à lista de operações:
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_rename_fields'), # <-- is this okay?
]
operations = [
migrations.RenameField('AnotherModel', 'foo', 'bar'),
migrations.RenameField('YetAnotherModel', 'foo', 'bar')
]
Etapa 8
Aplique a 2ª migração:
python manage.py migrate
Além de atualizar o restante do código (visualizações, formulários etc.) para refletir os novos nomes de variáveis, é basicamente assim que a nova funcionalidade de migração funcionaria?
Além disso, isso parece ter muitos passos. As operações de migração podem ser condensadas de alguma maneira?
Obrigado!
fonte
apps.get_model
-los. Levei muito tempo para descobrir isso../manage.py makemigrations myapp
comando perguntará se você renomeou o seu modelo. Por exemplo: você renomeou o modelo myapp.Foo para Bar? [s / N] Se você responder 's', a sua migração conterá asmigration.RenameModel('Foo', 'Bar')
mesmas contagens para os campos renomeados :-)manage.py makemigrations myapp
ainda pode falhar: "Talvez seja necessário adicionar manualmente isso se você alterar o nome do modelo e alguns de seus campos de uma só vez; para o detector automático, será como se você tivesse excluído um modelo com o nome antigo e adicionado um novo com um nome diferente e a migração criada perderá todos os dados da tabela antiga ". Docs do Django 2.1 Para mim, foi suficiente criar uma migração vazia, adicionar o nome do modelo a ela e executarmakemigrations
como de costume.