Last active
February 8, 2022 18:56
-
-
Save jamesmfriedman/6168003 to your computer and use it in GitHub Desktop.
Renaming a Django app that has migrations already sucks. This Is a way I found to do it that preserves your old migration history and keeps your contenttypes in order. The trick is, this migration cannot be in the app you are migrating, so stick it in your "core" app or another app you have installed. Just plug in your own old and new app names.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import datetime | |
from south.db import db | |
from south.v2 import SchemaMigration | |
from django.db import models | |
from django.db.models import get_app, get_models | |
class Migration(SchemaMigration): | |
# old_name => new_name | |
apps_to_rename = { | |
'some_old_app' : 'some_new_app', | |
'another_old_app' : 'another_new_app' | |
} | |
def forwards(self, orm): | |
for old_appname, new_appname in self.apps_to_rename.items(): | |
# Renaming model from 'Foo' to 'Bar' | |
db.execute("UPDATE south_migrationhistory SET app_name = %s WHERE app_name = %s", [new_appname, old_appname]) | |
db.execute("UPDATE django_content_type SET app_label = %s WHERE app_label = %s", [new_appname, old_appname]) | |
app = get_app(new_appname) | |
for model in get_models(app, include_auto_created=True): | |
if model._meta.proxy == True: | |
continue | |
new_table_name = model._meta.db_table | |
old_table_name = old_appname + new_table_name[len(new_appname):] | |
db.rename_table(old_table_name, new_table_name) | |
def backwards(self, orm): | |
for old_appname, new_appname in self.apps_to_rename.items(): | |
# Renaming model from 'Foo' to 'Bar' | |
db.execute("UPDATE south_migrationhistory SET app_name = %s WHERE app_name = %s", [old_appname, new_appname]) | |
db.execute("UPDATE django_content_type SET app_label = %s WHERE app_label = %s", [old_appname, new_appname]) | |
app = get_app(new_appname) | |
for model in get_models(app, include_auto_created=True): | |
if model._meta.proxy == True: | |
continue | |
old_table_name = model._meta.db_table | |
new_table_name = old_appname + old_table_name[len(new_appname):] | |
db.rename_table(old_table_name, new_table_name) | |
What I don't get from this post is an overall order-of-operations. When do I move the files (models, views, etc) from the old to the new? When can I delete the old safely? In my case, I have an app that I wrote called pages and I have a need to import mezzanine ... which has a sub-app called pages. So I need to rename my pages app to be able to use mezzanine.
@zBeeble42 that's why you should avoid generic names in future
@zBeeble42 instead of renaming your app, would you be able to use aliasing? e.g. from mezzanine import pages as mezzpages
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Could you instead get the models by querying based on the table's name, and filtering to only show ones that start with the app name?