S'appuyer sur Potr Czachur 's réponse Les situations impliquant des ForeignKeys sont plus compliquées et doivent être traitées de manière légèrement différente.
(L'exemple suivant s'appuie sur le common
y specific
Les applications auxquelles il est fait référence dans la présente réponse).
# common/models.py
class Cat(models.Model):
# ...
class Toy(models.Model):
belongs_to = models.ForeignKey(Cat)
# ...
deviendrait alors
# common/models.py
from specific.models import Cat
class Toy(models.Model):
belongs_to = models.ForeignKey(Cat)
# ...
# specific/models.py
class Cat(models.Model):
# ...
Running
./manage.py schemamigration common --auto
./manage.py schemamigration specific --auto # or --initial
générerait les migrations suivantes (j'ignore intentionnellement les changements de type de contenu de Django - voir la réponse précédemment référencée pour savoir comment gérer cela) :
# common/migrations/0009_auto__del_cat.py
class Migration(SchemaMigration):
def forwards(self, orm):
db.delete_table('common_cat')
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['specific.Cat']))
def backwards(self, orm):
db.create_table('common_cat', (
# ...
))
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['common.Cat']))
# specific/migrations/0004_auto__add_cat.py
class Migration(SchemaMigration):
def forwards(self, orm):
db.create_table('specific_cat', (
# ...
))
def backwards(self, orm):
db.delete_table('specific_cat')
Comme vous pouvez le voir, le FK doit être modifié pour faire référence à la nouvelle table. Nous devons ajouter une dépendance afin de connaître l'ordre dans lequel les migrations seront appliquées (et donc que la table existe avant que nous essayions d'y ajouter un FK) mais nous devons également nous assurer que le retour en arrière fonctionne également car la dépendance s'applique dans le sens inverse .
# common/migrations/0009_auto__del_cat.py
class Migration(SchemaMigration):
depends_on = (
('specific', '0004_auto__add_cat'),
)
def forwards(self, orm):
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['specific.Cat']))
def backwards(self, orm):
db.rename_table('specific_cat', 'common_cat')
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['common.Cat']))
# specific/migrations/0004_auto__add_cat.py
class Migration(SchemaMigration):
def forwards(self, orm):
db.rename_table('common_cat', 'specific_cat')
def backwards(self, orm):
pass
Par le Documentation sur le sud , depends_on
veillera à ce que 0004_auto__add_cat
s'exécute avant 0009_auto__del_cat
lors de la migration vers l'avant mais dans le ordre inverse lors de la migration vers l'arrière . Si nous avons laissé db.rename_table('specific_cat', 'common_cat')
dans le specific
rollback, le common
Le retour en arrière échouerait lors de la tentative de migration de la clé étrangère car la table référencée n'existerait pas.
J'espère que cette solution est plus proche d'une situation réelle que les solutions existantes et que quelqu'un la trouvera utile. À la vôtre !