Easiest way to rename a model using Django/South?

后端 未结 4 1797
無奈伤痛
無奈伤痛 2020-11-29 15:44

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.

4条回答
  •  再見小時候
    2020-11-29 15:50

    Make the changes in models.py and then run

    ./manage.py schemamigration --auto myapp
    

    When you inspect the migration file, you'll see that it deletes a table and creates a new one

    class Migration(SchemaMigration):
    
        def forwards(self, orm):
            # Deleting model 'Foo'                                                                                                                      
            db.delete_table('myapp_foo')
    
            # Adding model 'Bar'                                                                                                                        
            db.create_table('myapp_bar', (
            ...
            ))
            db.send_create_signal('myapp', ['Bar'])
    
        def backwards(self, orm):
            ...
    

    This is not quite what you want. Instead, edit the migration so that it looks like:

    class Migration(SchemaMigration):
    
        def forwards(self, orm):
            # Renaming model from 'Foo' to 'Bar'                                                                                                                      
            db.rename_table('myapp_foo', 'myapp_bar')                                                                                                                        
            if not db.dry_run:
                orm['contenttypes.contenttype'].objects.filter(
                    app_label='myapp', model='foo').update(model='bar')
    
        def backwards(self, orm):
            # Renaming model from 'Bar' to 'Foo'                                                                                                                      
            db.rename_table('myapp_bar', 'myapp_foo')                                                                                                                        
            if not db.dry_run:
                orm['contenttypes.contenttype'].objects.filter(app_label='myapp', model='bar').update(model='foo')
    

    In the absence of the update statement, the db.send_create_signal call will create a new ContentType with the new model name. But it's better to just update the ContentType you already have in case there are database objects pointing to it (e.g., via a GenericForeignKey).

    Also, if you've renamed some columns which are foreign keys to the renamed model, don't forget to

    db.rename_column(myapp_model, foo_id, bar_id)
    

提交回复
热议问题