Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Renaming a django model class-name and corresponding foreign keys with south, without loosing the data

Following is my model:

class myUser_Group(models.Model):
    name = models.CharField(max_length=100)


class Channel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    belongs_to_group = models.ManyToManyField(myUser_Group)

class Video(models.Model):
    video_url = models.URLField(max_length=300) 
    belongs_to_channel = models.ManyToManyField(Channel)
    description = models.CharField(max_length=1000)
    tags = TagField()

class UserProfile(models.Model):
       user = models.OneToOneField(User)

class User_History(models.Model):
    date_time = models.DateTimeField()
    user = models.ForeignKey(UserProfile, null=True, blank=True)
    videos_watched = models.ManyToManyField(Video)

I just wanted to remove the underscores from all the class names so that User_History looks UserHistory, also the foreign keys should be updated. I tried using south but could not find it in the documentaion.

One way is export the data, uninstall south, delete migration, rename the table and then import data again. Is there any other way to do it?

like image 294
whatf Avatar asked Sep 20 '11 12:09

whatf


People also ask

How do I rename a Django model?

When you change a model's name and run python manage.py makemigrations , you will get an autogenerated file in your migration. We want to rename Contact to ContactList in the Django model. After running the migrations, check the folder for the autogenerated file similar to below. class Migration(migrations.

What is __ str __ in Django?

The __str__ method in Python represents the class objects as a string – it can be used for classes. The __str__ method should be defined in a way that is easy to read and outputs all the members of the class. This method is also used as a debugging tool when the members of a class need to be checked.

Can a Django model have 2 foreign keys?

Models can have multiple foreign keys.


1 Answers

You can do this using just South.

For this example I have an app called usergroups with the following model:

class myUser_Group(models.Model):
    name = models.CharField(max_length=100)

which I assume is already under migration control with South.

Make the model name change:

class MyUserGroup(models.Model):
    name = models.CharField(max_length=100)

and create an empty migration from south

$ python manage.py schemamigration usergroups model_name_change --empty

This will create a skeleton migration file for you to specify what happens. If we edit it so it looks like this (this file will be in the app_name/migrations/ folder -- usergroups/migrations/ in this case):

import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Change the table name from the old model name to the new model name
        # ADD THIS LINE (using the correct table names)
        db.rename_table('usergroups_myuser_group', 'usergroups_myusergroup')


    def backwards(self, orm):
        # Provide a way to do the migration backwards by renaming the other way
        # ADD THIS LINE (using the correct table names)
        db.rename_table('usergroups_myusergroup', 'usergroups_myuser_group')


    models = {
        'usergroups.myusergroup': {
            'Meta': {'object_name': 'MyUserGroup'},
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
        }
    }

    complete_apps = ['usergroups']

In the forwards method we are renaming the database table name to match what the django ORM will look for with the new model name. We reverse the change in backwards to ensure the migration can be stepped back if required.

Run the migration with no need to import/export the exisiting data:

$ python manage.py migrate

The only step remaining is to update the foreign key and many-to-many columns in the models that refer to myUser_Group and change to refer to MyUserGroup.

like image 156
mmcnickle Avatar answered Sep 25 '22 04:09

mmcnickle