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?
db.rename_table('city_citystate', 'geo_citystate')
, but I'm not sure how to fix the foreign key in this case.In the current version of Django you can rename the model and run the python manage.py makemigrations , django will then ask if you want to rename the model and if you select yes, then all renaming process will be done automatically.
str function in a django model returns a string that is exactly rendered as the display name of instances for that model.
It is generally recommended to use singular nouns for model naming, for example: User, Post, Article. That is, the last component of the name should be a noun, e.g.: Some New Shiny Item. It is correct to use singular numbers when one unit of a model does not contain information about several objects.
Model Meta is basically the inner class of your model class. Model Meta is basically used to change the behavior of your model fields like changing order options,verbose_name, and a lot of other options. It's completely optional to add a Meta class to your model.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With