He estado buscando una respuesta a esto en el sitio de South, Google y SO, pero no pude encontrar una manera simple de hacerlo.
Quiero cambiar el nombre de un modelo de Django usando South. Digamos que tiene lo siguiente:
class Foo(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
y quieres convertir Foo a Bar, a saber
class Bar(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Bar)
Para simplificarlo, solo estoy tratando de cambiar el nombre de Foo
a Bar
, pero ignoro al foo
miembro FooTwo
por ahora.
¿Cuál es la forma más fácil de hacer esto usando South?
- Probablemente podría hacer una migración de datos, pero eso parece bastante complicado.
- Escriba una migración personalizada, por ejemplo
db.rename_table('city_citystate', 'geo_citystate')
, pero no estoy seguro de cómo solucionar la clave externa en este caso. - ¿Una forma más fácil que sabes?
python
django
django-models
rename
django-south
Vaughnkoch
fuente
fuente
Respuestas:
Para responder a su primera pregunta, el simple cambio de nombre de modelo / tabla es bastante sencillo. Ejecute el comando:
(Actualización 2: intente en
--auto
lugar de--empty
evitar la advertencia a continuación. Gracias a @KFB por el consejo).Si está utilizando una versión anterior de south, necesitará en
startmigration
lugar deschemamigration
.Luego edite manualmente el archivo de migración para que se vea así:
Puede lograr esto más simplemente usando la
db_table
opción Meta en su clase de modelo. Pero cada vez que hace eso, aumenta el peso heredado de su base de código: tener nombres de clase diferentes de los nombres de tabla hace que su código sea más difícil de entender y mantener. Apoyo totalmente hacer refactorizaciones simples como esta en aras de la claridad.(actualización) Acabo de intentar esto en producción y recibí una advertencia extraña cuando fui a aplicar la migración. Decía:
Respondí "no" y todo parecía estar bien.
fuente
Haz los cambios
models.py
y luego ejecutaCuando inspeccione el archivo de migración, verá que elimina una tabla y crea una nueva.
Esto no es exactamente lo que quieres. En su lugar, edite la migración para que se vea así:
En ausencia de la
update
declaración, ladb.send_create_signal
llamada creará una nuevaContentType
con el nuevo nombre del modelo. Pero es mejor soloupdate
loContentType
que ya tiene en caso de que haya objetos de base de datos que lo señalen (por ejemplo, a través de aGenericForeignKey
).Además, si ha cambiado el nombre de algunas columnas que son claves foráneas para el modelo renombrado, no olvide
fuente
contenttypes.ContentType
modelo a los modelos congelados usando el--frozen
indicador a./manage.py datamigration
. Por ejemplo:./manage.py datamigration --frozen contenttypes myapp update_contenttypes
. Luego edite myapp_migrations / NNNN_update_contenttypes.py con el código de actualización del tipo de contenido como se especificó anteriormente.South no puede hacerlo por sí mismo: ¿cómo sabe que
Bar
representa lo queFoo
solía ser? Este es el tipo de cosas para las que escribiría una migración personalizada. Puede cambiar suForeignKey
código de entrada como lo hizo anteriormente, y luego solo se trata de cambiar el nombre de los campos y tablas apropiados, lo que puede hacer de la forma que desee.Finalmente, ¿realmente necesitas hacer esto? Todavía tengo que cambiar el nombre de los modelos; los nombres de los modelos son solo un detalle de implementación, particularmente dada la disponibilidad de la
verbose_name
opción Meta.fuente
db_table
opción Meta para mantener el mismo nombre de la tabla de la base de datos.db_table
se usa para derivar nombres de claves externas?Seguí la solución de Leopd anterior. Pero eso no cambió los nombres de los modelos. Lo cambié manualmente en el código (también en modelos relacionados donde esto se conoce como FK). Y realizó otra migración al sur, pero con la opción --fake. Esto hace que los nombres de modelo y de tabla sean iguales.
Acabo de darme cuenta, primero se puede comenzar cambiando los nombres de los modelos, luego editar el archivo de migraciones antes de aplicarlos. Mucho más limpio.
fuente