template python django django-models django-south

python - template - Django-¿Cómo cambiar el nombre de un campo de modelo usando South?



include django (6)

Me gustaría cambiar un nombre de campos específicos en un modelo:

class Foo(models.Model): name = models.CharField() rel = models.ForeignKey(Bar)

debe cambiar a

class Foo(models.Model): full_name = models.CharField() odd_relation = models.ForeignKey(Bar)

¿Cuál es la forma más fácil de hacer esto usando South?


  1. Agregue el south a sus aplicaciones instaladas en el archivo de configuración del proyecto.
  2. Comente el campo / tabla agregada / modificada.
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. Anule el comentario del campo y escriba el modificado.
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

Si está utilizando ''pycharm'', entonces puede usar ''ctrl + shift + r'' en lugar de ''manage.py'', y ''shift'' para los parámetros.


Django 1.7 introdujo Migrations por lo que ahora ni siquiera necesita instalar un paquete adicional para administrar sus migraciones.

Para cambiar el nombre de su modelo, primero debe crear una migración vacía:

$ manage.py makemigrations <app_name> --empty

Entonces necesitas editar el código de tu migración de esta manera:

from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ (''yourapp'', ''XXXX_your_previous_migration''), ] operations = [ migrations.RenameField( model_name=''Foo'', old_name=''name'', new_name=''full_name'' ), migrations.RenameField( model_name=''Foo'', old_name=''rel'', new_name=''odd_relation'' ), ]

Y después de eso necesitas correr:

$ manage.py migrate <app_name>


Esto es lo que hago:

  1. Cambie el nombre de la columna en su modelo (en este ejemplo sería myapp/models.py )
  2. Ejecute ./manage.py schemamigration myapp renaming_column_x --auto

Tenga en cuenta que renaming_column_x puede ser lo que quiera, es solo una forma de dar un nombre descriptivo al archivo de migración.

Esto le generará un archivo llamado myapp/migrations/000x_renaming_column_x.py que eliminará su columna anterior y agregará una nueva columna.

Modifique el código en este archivo para cambiar el comportamiento de la migración a un simple cambio de nombre:

class Migration(SchemaMigration): def forwards(self, orm): # Renaming column ''mymodel.old_column_name'' to ''mymodel.new_column_name'' db.rename_column(u''myapp_mymodel'', ''old_column_name'', ''new_column_name'') def backwards(self, orm): # Renaming column ''mymodel.new_column_name'' to ''mymodel.old_column_name'' db.rename_column(u''myapp_mymodel'', ''new_column_name'', ''old_column_name'')


No sabía acerca de la columna db.rename, suena práctico, sin embargo, en el pasado, he agregado la nueva columna como una schemamigration, luego creé una datamigration para mover valores al nuevo campo, luego un segundo schemamigration para eliminar la columna anterior


Puede utilizar la función db.rename_column .

class Migration: def forwards(self, orm): # Rename ''name'' field to ''full_name'' db.rename_column(''app_foo'', ''name'', ''full_name'') def backwards(self, orm): # Rename ''full_name'' field to ''name'' db.rename_column(''app_foo'', ''full_name'', ''name'')

El primer argumento de db.rename_column es el nombre de la tabla, por lo que es importante recordar cómo Django crea los nombres de las tablas :

Django deriva automáticamente el nombre de la tabla de la base de datos del nombre de su clase de modelo y la aplicación que lo contiene. El nombre de la tabla de la base de datos de un modelo se construye uniendo la "etiqueta de aplicación" del modelo, el nombre que usó en manage.py startapp, al nombre de clase del modelo, con un subrayado entre ellos.

En el caso de que tenga un nombre de modelo con varias letras en camello, como ProjectItem, el nombre de la tabla será app_projectitem (es decir, no se insertará un guión bajo entre el project y el item aunque estén en camel).


Solo cambia el modelo y ejecuta makemigrations en 1.9

Django detecta automáticamente que ha eliminado y creado un solo campo y le pregunta:

Did you rename model.old to model.new (a IntegerField)? [y/N]

Di que sí, y se crea la migración correcta. Mágico.