How to remove an app from a django projects (and all its tables)
Question: I want to remove an app from a django project.

I want to remove

  * the tables of the app
  * the content-types
  * foreign-key usages of these content-types

Running `manage.py migrate app_to_remove zero` does not work:

    
    
    django.db.migrations.migration.IrreversibleError: 
    Operation <RunPython <function forwards_func at 0x7ff76075d668>> in
                fooapp.0007_add_bar is not reversible
    

I guess there are several migrations which are not reversible ...


Answer: # First: Remove references in the code

  * remove `app_to_remove` from `settings.INSTALLED_APPS`
  * remove other references in `urls.py` or other places

# Second: Clean the database

Create an empty migration for your django-project:

    
    
    manage.py makemigrations your_django_project --empty
    

Edit the file. Here is a template:

    
    
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.db import migrations, models
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('your_django_project', '0001_initial'),
        ]
    
        operations = [
            migrations.RunSQL('''
            drop if exists table app_to_remove_table1;
            drop if exists table app_to_remove_table2;
            ....
            delete from auth_permission where content_type_id in (select id from django_content_type where app_label = '{app_label}');
            delete from django_admin_log where content_type_id in (select id from django_content_type where app_label = '{app_label}');
            delete from reversion_version where content_type_id in (select id from django_content_type where app_label = '{app_label}');
            delete from django_content_type where app_label = '{app_label}';
            delete from django_migrations where app='{app_label}';
            '''.format(app_label='app_to_remove'))
        ]
    

Run the migration, run tests.

About "drop if exists": You have two cases:

  1. The production system: You want to drop the tables.
  2. New development systems: These systems never had this app, and they don't have this table :-)

