How do I rename a model with Django?

2019-07-20 02:57发布

问题:

Let's say I have this model:

class Foo(models.Model):
    name = models.CharField(max_length=255)

I want to rename it to Bar. What steps should I take? And how do I deal with The following content types are stale prompt?

回答1:

In my particular case it was like so:

  1. Rename model class name and all its references.
  2. Run ./manage.py makemigrations.
  3. Inspect your database for references from tables your apps own. Ordinary references and references via django_content_type table. Deal with them accordingly.
  4. Inspect your database for references from Django tables. Most likely that would be:

    my_table-+-django_admin_log
             `-auth_permission-+-auth_group_permissions
                               `-auth_user_user_permissions
    

    In my case I had no records in django_admin_log, auth_group_permissions, auth_user_user_permissions.

  5. Run ./manage.py migrate. When it asks:

    The following content types are stale and need to be deleted:                
    
        myapp | 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'.                                                  
    
        Type 'yes' to continue, or 'no' to cancel:
    

    You can answer yes only if you have no records referencing records in foo table in the three tables mentioned above. Or if losing them is not an issue for you.



回答2:

Side note:

In some cases, when you change a model's name and then run python manage.py makemigrations, you'll see that the autogenerated migration is adding the new model and then deleting the old model (field by field, and then the model itself).

If that happens, then you may get this error when you try to run python manage.py migrate:

django.db.utils.IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails')

To get around this issue: open up the autogenerated migration file and edit it manually, like so:

operations = [
        migrations.RenameModel('Foo', 'Bar'),
    ]

Then run the python manage.py migrate again.