4. Safely move a model between apps

  1. Move the model class into the new app

For example, moving MyClass from old_app.models to new_app.models.

new_app/models.py
1class MyClass(models.Model):
2    # your fields here
3    ...
4
5    class Meta:
6        db_table = "old_app_myclass"  # keep the same table name as before!

👉 This ensures the new model points to the existing table, not a new one.

  1. Create a manual migration in the new app

Run: python manage.py makemigrations new_app

This will likely create a CreateModel migration. Edit it manually to use migrations.SeparateDatabaseAndState, which lets you tell Django “don’t touch the DB table, only update Django’s state.”

new_app/migrations/0001_initial.py
 1from django.db import migrations, models
 2
 3class Migration(migrations.Migration):
 4
 5    initial = True
 6
 7    dependencies = [
 8        ("old_app", "XXXX_previous_migration"),
 9    ]
10
11    operations = [
12        migrations.SeparateDatabaseAndState(
13            state_operations=[
14                # Take the migrations.CreateModel from the auto-generated migration!
15                migrations.CreateModel(
16                    name="MyClass",
17                    fields=[
18                        ...
19                    ],
20                    options={"db_table": "old_app_myclass"},
21                ),
22            ],
23            database_operations=[],
24        ),
25    ]

👉 This way, Django updates its model state but doesn’t actually create/drop the table.

  1. Remove the model from the old app

Delete it from old_app/models.py.

Then run: python manage.py makemigrations old_app

That will generate a DeleteModel. Edit it manually so it only removes the model from Django’s state, not the DB:

old_app/migrations/XXXX_remove_myclass.py
 1from django.db import migrations
 2
 3class Migration(migrations.Migration):
 4
 5    dependencies = [
 6        ("old_app", "XXXX_previous_migration"),
 7    ]
 8
 9    operations = [
10        migrations.SeparateDatabaseAndState(
11            state_operations=[
12                # Take the migrations.DeleteModel from the auto-generated migration!
13                migrations.DeleteModel(name="MyClass"),
14            ],
15            database_operations=[],
16        ),
17    ]
  1. Remove the db_table in new_app/models.py

new_app/models.py
1class MyClass(models.Model):
2    # your fields here
3    ...
4
5    # class Meta: <-- remove!
6    #    db_table = "old_app_myclass" <-- remove!
  1. Create auto migrations: python manage.py makemigrations new_app

This will generate a migrations to update the db_table on the MyClass model in new_app to use the default one (instead of the old_app_myclass)

  1. Apply migrations python manage.py migrate

Now:

  • Django knows the model is in the new app.

  • The db_table has been updated, and all the relation also

  • The default DB table from django is used

  • No data is lost. 🎉

Tags: Django, Python, Model, App, Move, Data, db_table