Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Renommer un modèle django (>=1.7)

+3 votes

Mon projet django comporte un modèle Foo que j'ai besoin de renommer en Bar. Simplement, d'autres modèles le référencent sous forme de ForeignKey, et j'ai déjà des données existantes dans la BDD.

Pour simplifier, au départ j'ai ça :

class Parent(models.Model):
    pass

class Foo(models.Model):

    parent = models.ForeignKey(Parent, related_name="children")

class FooComment(models.Model):

    subject = models.ForeignKey(Foo, related_name="comments")

Et je voudrais arriver à :

class Parent(models.Model):
    pass

class Bar(models.Model):

    parent = models.ForeignKey(Parent, related_name="children")

class BarComment(models.Model):

    subject = models.ForeignKey(Bar, related_name="comments")

L'idéal serait de le faire avec une migration django (pas South, mais depuis l'outil natif de Django depuis la 1.7) mais je ne sais pas par où commencer. Toutes les réponses que j'ai trouvé sur ce cas précis concernent South.

demandé 17-Jan-2015 par eliotberriot (678 points)

Heum, ouate heubaout, zis:

$ python manage.py makemigrations; # generer un script de migrations

Et ensuite, appliquer le script de migrations:

$ python manage.py migrate; # appliquer les migrations

Je connais les commandes de base pour gérer les migrations sous django. Je me suis peut-être mal exprimé, ma demande porte plus sur la procédure à suivre pour :

  1. Changer le nom du modèle
  2. Mettre à jour le nom du modèle dans les autres modèles

Est-ce que je dois d'abord renommer mon modèle Foo en Bar partout où il est référencé dans les fichiers pythons, mettre à jour cette première table, pour ensuite générer des migrations pour chacun des modèles qui le référencent ? Vaut-il mieux faire tout dans une seule migration ? Quelqu'un aurait-il un exemple vraiment basique du code à mettre dans une telle migration ?

@eliotberriot j'attendais de toi que tu l'essaies en vrai et que tu nous dises si t'a eu des exceptions, mais oui, en gros c'est:

  • changer le nom du modele,
  • dans ton code, partout ou tu avais Foo, remplacer par Bar.
  • generer le script de migrations.
  • appliquer les migrations.

Il peut arriver de devoir toi meme modifier le script de migration. Voici une bonne source d'inspiration

Eliotberriot — en tout cas il ne faut pas t'inquiéter, c'est pas très grave si tu casses tout, mais fait des dumps de ta base avant si tu as des données. Sinon tu peux tout supprimer et repartir sur un syncdb tout propre.

En général quand je suis en développement et que je suis seul je ne m'embête pas trop avec des migrations à chaque fois je regénere tout mon modèle de données.

En passant ce que tu as sûrement lu sur South s'applique à Django 1.7, c'est juste pas les mêmes commandes, mais les mêmes principes.

Et comme le dit Nsukami_ pour un cas aussi simple tu as juste à remplacer les pointeurs de Foo par Bar en une seule fois.

@Hawke c'est ce que je fais quand j'en ai la possibilité, mais la malheureusement, je dois le faire proprement, car j'ai plusieurs instances de ce projet en fonctionnement et il me parait préférable de gérer ça de façon automatisée.

J'ai également été un peu vite sur la simplification de mon problème, car j'ai aussi des modèles qui héritent de Foo (héritage concret de Django), ce qui complexifie les choses.

Il s'agit très précisément de ce modèle, si vous voulez jeter un oeil par curiosité.

J'ai bien pris note de toutes vos réponses, je reviendrai accepter la réponse de Hawke et vous dire ce qu'il en est lorsque j'aurais effectué la migration.

1 Réponse

+4 votes

Tu peux utiliser la commande pour générer les migrations sur ton modèle contenant Foo après avoir appliqué les changements en Bar au code :

$ ./manage.py makemigrations

La commande Django va te poser des questions pour voir si tu es bien sûr de toi. Ici un truc du genre :

Did you rename the monapp.Foo model to Bar? [y/N] 
Did you rename the monapp.FooComment model to BarComment? [y/N] 

Donc tu vas générer un fichier de migration qui va se trouver dans le dossier monapp/migrations/000*_auto_DATE_HEURE.py ensuite pour appliquer ce fichier de migration tu va faire un :

$ ./manage.py migrate

Si tu regardes le fichier généré tu verras que c'est très clair de comprendre ce qui est écrit dedans.

répondu 18-Jan-2015 par Hawke (466 points)
...