web-dev-qa-db-fra.com

Django - Comment renommer un champ de modèle en utilisant Sud?

Je voudrais changer le nom de champs spécifiques dans un modèle:

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

devrait changer à:

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

Quelle est la façon la plus simple de faire cela en utilisant South?

208
Jonathan

Vous pouvez utiliser le db.rename_column fonction.

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

Le premier argument de db.rename_column est le nom de la table, il est donc important de se rappeler comment Django crée des noms de table :

Django tire automatiquement le nom de la table de la base de données du nom de votre classe de modèle et de l'application qui la contient. Le nom de la table de base de données d'un modèle est construit en reliant le "libellé d'application" du modèle, le nom que vous avez utilisé dans manage.py startapp, au nom de classe du modèle, avec un trait de soulignement entre eux.

Dans le cas où vous avez un nom de modèle multilingue, tel que ProjectItem, le nom de modèle est chameau, le nom de la table sera app_projectitem (c’est-à-dire qu’un trait de soulignement ne sera pas inséré entre project et item même s’ils sont camelés).

229
googletorp

Voici ce que je fais:

  1. Modifiez le nom de la colonne dans votre modèle (dans cet exemple, il s'agirait de myapp/models.py)
  2. Courir ./manage.py schemamigration myapp renaming_column_x --auto

Remarque renaming_column_x peut être ce que vous voulez, c'est juste une façon de donner un nom descriptif au fichier de migration.

Cela vous générera un fichier nommé myapp/migrations/000x_renaming_column_x.py qui supprimera votre ancienne colonne et ajoutera une nouvelle colonne.

Modifiez le code dans ce fichier pour modifier le comportement de la migration en un simple changement de nom:

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')
39
donturner

Je ne connaissais pas la colonne db.rename, cela me semble pratique, mais j’ai précédemment ajouté la nouvelle colonne en tant que migration unique, puis créé une migration de données pour déplacer les valeurs dans le nouveau champ, puis une seconde migration pour supprimer l’ancienne colonne.

15
sjh

Django 1.7 a introduit Migrations vous n'avez donc plus besoin d'installer de paquet supplémentaire pour gérer vos migrations.

Pour renommer votre modèle, vous devez d'abord créer une migration vide:

$ manage.py makemigrations <app_name> --empty

Ensuite, vous devez éditer le code de votre migration comme ceci:

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

Et après cela, vous devez courir:

$ manage.py migrate <app_name>
9
Dmitrii Mikhailov

Il suffit de changer le modèle et d’exécuter makemigrations dans 1.9

Django détecte automatiquement que vous avez supprimé et créé un seul champ et demande:

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

Dites oui et la bonne migration est créée. La magie.

  1. Ajoutez south à vos applications installées dans le fichier de paramétrage du projet.
  2. Mettez en commentaire le champ/la table ajouté/modifié.
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. Décommentez le champ et écrivez le champ modifié
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

Si vous utilisez "pycharm", vous pouvez utiliser "ctrl + shift + r" au lieu de "manage.py" et "shift" pour les paramètres.

0
ancho