Easiest way to rename a model using Django/South?
django, django-models, django-south, python, rename
Solution
To answer your first question, the simple model/table rename is pretty straightforward. Run the command:
./manage.py schemamigration yourapp rename_foo_to_bar --empty
(Update 2: try `--auto` instead of `--empty` to avoid the warning below. Thanks to @KFB for the tip.)
If you're using an older version of south, you'll need `startmigration` instead of `schemamigration`.
Then manually edit the migration file to look like this:
class Migration(SchemaMigration):
def forwards(self, orm):
db.rename_table('yourapp_foo', 'yourapp_bar')
def backwards(self, orm):
db.rename_table('yourapp_bar','yourapp_foo')
You can accomplish this more simply using the `db_table` Meta option in your model class. But every time you do that, you increase the legacy weight of your codebase -- having class names differ from table names makes your code harder to understand and maintain. I fully support doing simple refactorings like this for the sake of clarity.
(update) I just tried this in production, and got a strange warning when I went to apply the migration. It said:
The following content types are stale and need to be deleted:
yourapp | foo
Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.
I answered "no" and everything seemed to be fine.
Problem
I've been hunting for an answer to this on South's site, Google, and SO, but couldn't find a simple way to do this. I want to rename a Django model using South. Say you have the following: ``` class Foo(models.Model): name = models.CharField() class FooTwo(models.Model): name = models.CharField() foo = models.ForeignKey(Foo) ``` and you want to convert Foo to Bar, namely ``` class Bar(models.Model): name = models.CharField() class FooTwo(models.Model): name = models.CharField() foo = models.ForeignKey(Bar) ``` To keep it simple, I'm just trying to change the name from `Foo` to `Bar`, but ignore the `foo` member in `FooTwo` for now. What's the easiest way to do this using South? - I could probably do a data migration, but that seems pretty involved. - Write a custom migration, e.g. `db.rename_table('city_citystate', 'geo_citystate')`, but I'm not sure how to fix the foreign key in this case. - An easier way that you know?