J'ai cherché une réponse à cela sur le site de South, Google et SO, mais je n'ai pas trouvé de moyen simple de le faire.
Je souhaite renommer un modèle Django en utilisant South. Disons que vous avez ce qui suit:
class Foo(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
et vous voulez convertir Foo en Bar, à savoir
class Bar(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Bar)
Pour faire simple, j'essaie simplement de changer le nom de Foo
en Bar
, mais ignorez le foo
membre FooTwo
pour le moment.
Quelle est la façon la plus simple de faire cela en utilisant South?
- Je pourrais probablement faire une migration de données, mais cela semble assez compliqué.
- Écrivez une migration personnalisée, par exemple
db.rename_table('city_citystate', 'geo_citystate')
, mais je ne suis pas sûr de savoir comment réparer la clé étrangère dans ce cas. - Un moyen plus simple que vous connaissez?
python
django
django-models
rename
django-south
Vaughnkoch
la source
la source
Réponses:
Pour répondre à votre première question, le simple changement de nom de modèle / table est assez simple. Exécutez la commande:
(Mise à jour 2: essayez
--auto
plutôt que d'--empty
éviter l'avertissement ci-dessous. Merci à @KFB pour le conseil.)Si vous utilisez une ancienne version de south, vous aurez besoin à la
startmigration
place deschemamigration
.Ensuite, modifiez manuellement le fichier de migration pour qu'il ressemble à ceci:
Vous pouvez accomplir cela plus simplement en utilisant l'
db_table
option Meta dans votre classe de modèle. Mais chaque fois que vous faites cela, vous augmentez le poids hérité de votre base de code - avoir des noms de classe différents des noms de table rend votre code plus difficile à comprendre et à maintenir. Je soutiens pleinement les refactorisations simples comme celle-ci dans un souci de clarté.(mise à jour) Je viens d'essayer cela en production et j'ai reçu un étrange avertissement lorsque je suis allé appliquer la migration. Ça disait:
J'ai répondu "non" et tout semblait aller bien.
la source
Apportez les modifications
models.py
et exécutezLorsque vous inspectez le fichier de migration, vous verrez qu'il supprime une table et en crée une nouvelle
Ce n'est pas tout à fait ce que vous voulez. Au lieu de cela, modifiez la migration pour qu'elle ressemble à:
En l'absence de
update
déclaration, l'db.send_create_signal
appel créera un nouveauContentType
avec le nouveau nom de modèle. Mais il vaut mieux justeupdate
le queContentType
vous avez déjà au cas où il y aurait des objets de base de données pointant vers lui (par exemple, via aGenericForeignKey
).De plus, si vous avez renommé certaines colonnes qui sont des clés étrangères du modèle renommé, n'oubliez pas de
la source
contenttypes.ContentType
modèle aux modèles gelés en utilisant l'--frozen
indicateur to./manage.py datamigration
. Par exemple:./manage.py datamigration --frozen contenttypes myapp update_contenttypes
. Puis modifiez myapp_migrations / NNNN_update_contenttypes.py avec le code de mise à jour du type de contenu comme spécifié ci-dessus.Le Sud ne peut pas le faire lui-même - comment sait-il que cela
Bar
représente ce qui étaitFoo
autrefois? C'est le genre de chose pour laquelle j'écrirais une migration personnalisée. Vous pouvez modifier votreForeignKey
code comme vous l'avez fait ci-dessus, puis il vous suffit de renommer les champs et les tables appropriés, ce que vous pouvez faire comme vous le souhaitez.Enfin, avez-vous vraiment besoin de faire cela? Je n'ai pas encore besoin de renommer les modèles - les noms de modèles ne sont qu'un détail d'implémentation - en particulier compte tenu de la disponibilité de l'
verbose_name
option Meta.la source
db_table
option Meta pour conserver le même nom de table de base de données.db_table
est utilisé pour dériver des noms de clés étrangères?J'ai suivi la solution de Leopd ci-dessus. Mais cela n'a pas changé les noms des modèles. Je l'ai changé manuellement dans le code (également dans les modèles associés où cela s'appelle FK). Et fait une autre migration vers le sud, mais avec l'option --fake. Cela rend les noms de modèle et les noms de table identiques.
A peine réalisé, on peut commencer par changer les noms de modèle, puis éditer le fichier de migrations avant de les appliquer. Beaucoup plus propre.
la source