2011-09-20 14 views
6

siguiente es mi modelo:Cambiar el nombre de una clase-nombre del modelo Django y las claves externas con el sur correspondiente, sin perder los datos

class myUser_Group(models.Model): 
    name = models.CharField(max_length=100) 


class Channel(models.Model): 
    name = models.CharField(max_length=100) 
    description = models.CharField(max_length=1000) 
    belongs_to_group = models.ManyToManyField(myUser_Group) 

class Video(models.Model): 
    video_url = models.URLField(max_length=300) 
    belongs_to_channel = models.ManyToManyField(Channel) 
    description = models.CharField(max_length=1000) 
    tags = TagField() 

class UserProfile(models.Model): 
     user = models.OneToOneField(User) 

class User_History(models.Model): 
    date_time = models.DateTimeField() 
    user = models.ForeignKey(UserProfile, null=True, blank=True) 
    videos_watched = models.ManyToManyField(Video) 

Sólo quería eliminan los guiones de todos los nombres de las clases de manera que User_History mira UserHistory, también las llaves foráneas deben ser actualizadas. Intenté usar el sur pero no pude encontrarlo en la documentación.

Una forma es exportar los datos, desinstalar al sur, eliminar la migración, cambiar el nombre de la tabla y luego importar datos de nuevo. ¿Hay alguna otra forma de hacerlo?

+0

y desea que este hecho en administrador? si es así, http://stackoverflow.com/questions/7413488/where-do-i-customize-the-heading-for-the-modeladmin-view/7414247#7414247 debería ayudar – Pannu

+0

Sí, es muy cierto. pero aún necesito cambiar los nombres de los modles, por adherencia a pep-8. – whatf

Respuesta

8

Puede hacerlo usando solo Sur.

Para este ejemplo tengo una aplicación llamada usergroups con el siguiente modelo:

class myUser_Group(models.Model): 
    name = models.CharField(max_length=100) 

que yo supongo que ya está bajo el control de la migración con el Sur.

hacer el cambio de nombre del modelo:

class MyUserGroup(models.Model): 
    name = models.CharField(max_length=100) 

y crear un vacío migración de sur

$ python manage.py schemamigration usergroups model_name_change --empty 

Esto creará un archivo de migración esqueleto para que especifique qué pasa. Si editamos para que se vea como esto (este archivo estará en el nombre_apl/migraciones/carpeta - Grupos/migraciones/en este caso):

import datetime 
from south.db import db 
from south.v2 import SchemaMigration 
from django.db import models 

class Migration(SchemaMigration): 

    def forwards(self, orm): 
     # Change the table name from the old model name to the new model name 
     # ADD THIS LINE (using the correct table names) 
     db.rename_table('usergroups_myuser_group', 'usergroups_myusergroup') 


    def backwards(self, orm): 
     # Provide a way to do the migration backwards by renaming the other way 
     # ADD THIS LINE (using the correct table names) 
     db.rename_table('usergroups_myusergroup', 'usergroups_myuser_group') 


    models = { 
     'usergroups.myusergroup': { 
      'Meta': {'object_name': 'MyUserGroup'}, 
      'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 
      'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) 
     } 
    } 

    complete_apps = ['usergroups'] 

En el método forwards estamos cambiando el nombre del nombre de la tabla de base de datos para que coincida con lo que el django ORM buscará con el nuevo nombre del modelo. Revertimos el cambio en backwards para asegurar que la migración se puede reducir si es necesario.

ejecutar la migración sin necesidad de importar/exportar los datos exisiting:

$ python manage.py migrar

El único paso que queda es actualizar la clave externa y muchos-a-muchos en columnas los modelos que hacen referencia a myUser_Group y cambian para referirse a MyUserGroup.

1

La solución de mmcnickle puede funcionar y parece razonable, pero prefiero un proceso de dos pasos. En el primer paso, cambia el nombre de la tabla.

En su modelo de asegurarse de que su nuevo nombre de tabla en:

class Meta: 
     db_table = new_table_name' 

Luego, como mmcnickle sugirió, crear una migración personalizada:

python manage.py schemamigration xyz migration_name --empty 

Usted puede leer más sobre esto aquí: https://docs.djangoproject.com/en/dev/ref/models/options/

Ahora con su migración personalizada también agregue la línea para cambiar el nombre de su tabla hacia adelante y hacia atrás:

db.rename_table("old_table_name","new_table_name") 

Esto puede ser suficiente para migrar y cambiar el nombre de la tabla, pero si antes ha utilizado el nombre de la tabla personalizada de Class Meta, tendrá que hacer un poco más. Así que, como regla general, solo para estar seguro haga una búsqueda en su archivo de migración para "old_table_name" y cambie las entradas que encuentre al nuevo nombre de la tabla. Por ejemplo, si previamente estaba utilizando el nombre de la tabla personalizada Meta clase, es probable que vea:

'Meta': {'object_name': 'ModelNameYouWillChangeNext', 'db_table': "u'old_table_name'"}, 

por lo que tendrá que cambiar el viejo nombre de la tabla a la nueva.

Ahora se puede migrar con:

python manage.py migrate xyz 

En este punto su aplicación debe ejecutarse desde todo lo que han hecho es cambiar el nombre de la tabla y decirle a Django a buscar el nuevo nombre de la tabla.

El segundo paso es cambiar el nombre de su modelo. La dificultad de esto realmente depende de su aplicación, pero básicamente solo necesita cambiar todo el código que hace referencia al nombre del modelo antiguo al código que hace referencia al nuevo nombre del modelo. También es probable que necesite cambiar algunos nombres de archivos y nombres de directorios si ha utilizado su antiguo nombre de modelo para fines de organización.

Después de hacer esto, su aplicación debería funcionar bien. En este punto, su tarea se ha completado bastante y su aplicación debería funcionar correctamente con un nuevo nombre de modelo y un nuevo nombre de tabla. El único problema con el que se encontrará al usar South es la próxima vez que cree una migración mediante su función de detección automática, intentará eliminar la tabla anterior y crear una nueva desde cero porque ha detectado su nuevo nombre de modelo. Para solucionar este problema es necesario crear otra migración personalizada:

python manage.py schemamigration xyz tell_south_we_changed_the_model_name_for_old_model_name --empty 

Lo bueno es que aquí no se hace nada, puesto que ya ha cambiado el nombre del modelo de manera Sur recoge esto. Sólo migrar con "pase" en el migran hacia delante y hacia atrás:

python manage.py migrate xyz 

No se hace nada y el Sur ahora se da cuenta de que está al día. Proveedores:

python manage.py schemamigration xyz --auto 

y debería ver detecta nada ha cambiado

Cuestiones relacionadas