Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easiest way to rename a model using Django/South?

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?

  1. I could probably do a data migration, but that seems pretty involved.
  2. 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.
  3. An easier way that you know?
like image 740
vaughnkoch Avatar asked May 19 '10 05:05

vaughnkoch


People also ask

How do I rename a Django model?

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.

What is Django __ str __?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model.

Should Django model names be plural?

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.

What is model meta in Django?

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.


1 Answers

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.

like image 139
Leopd Avatar answered Sep 19 '22 13:09

Leopd