Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - How to rename a model field using South?

People also ask

How can we rename the field?

Right-click the field whose name you want to change and click Rename Field. Type a new Field Name.

What is __ Str__ in Django?

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

How do you add a new field to a model with new Django migrations?

To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB.


You can use the db.rename_column function.

class Migration:

    def forwards(self, orm):
        # Rename 'name' field to 'full_name'
        db.rename_column('app_foo', 'name', 'full_name')




    def backwards(self, orm):
        # Rename 'full_name' field to 'name'
        db.rename_column('app_foo', 'full_name', 'name')

The first argument of db.rename_column is the table name, so it's important to remember how Django creates table names:

Django automatically derives the name of the database table from the name of your model class and the app that contains it. A model's database table name is constructed by joining the model's "app label" -- the name you used in manage.py startapp -- to the model's class name, with an underscore between them.

In the case where you have a multi-worded, camel-cased model name, such as ProjectItem, the table name will be app_projectitem (i.e., an underscore will not be inserted between project and item even though they are camel-cased).


Here's what I do:

  1. Make the column name change in your model (in this example it would be myapp/models.py)
  2. Run ./manage.py schemamigration myapp renaming_column_x --auto

Note renaming_column_x can be anything you like, it's just a way of giving a descriptive name to the migration file.

This will generate you a file called myapp/migrations/000x_renaming_column_x.py which will delete your old column and add a new column.

Modify the code in this file to change the migration behaviour to a simple rename:

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Renaming column 'mymodel.old_column_name' to 'mymodel.new_column_name'
        db.rename_column(u'myapp_mymodel', 'old_column_name', 'new_column_name')

    def backwards(self, orm):
        # Renaming column 'mymodel.new_column_name' to 'mymodel.old_column_name'
        db.rename_column(u'myapp_mymodel', 'new_column_name', 'old_column_name')

I didn't know about db.rename column, sounds handy, however in the past I have added the new column as one schemamigration, then created a datamigration to move values into the new field, then a second schemamigration to remove the old column


Django 1.7 introduced Migrations so now you don't even need to install extra package to manage your migrations.

To rename your model you need to create empty migration first:

$ manage.py makemigrations <app_name> --empty

Then you need to edit your migration's code like this:

from django.db import models, migrations

class Migration(migrations.Migration):

dependencies = [
    ('yourapp', 'XXXX_your_previous_migration'),
]

operations = [
    migrations.RenameField(
        model_name='Foo',
        old_name='name',
        new_name='full_name'
    ),
    migrations.RenameField(
        model_name='Foo',
        old_name='rel',
        new_name='odd_relation'
    ),
]

And after that you need to run:

$ manage.py migrate <app_name>

Just change the model and run makemigrations in 1.9

Django automatically detects that you've deleted and created a single field, and asks:

Did you rename model.old to model.new (a IntegerField)? [y/N]

Say yes, and the right migration gets created. Magic.