While pruning features from our product it was necessary to fully remove some Django apps that had models in them. If the code is just removed than the tables (and some other references) will be left in the database.
After doing this a few times for work I came up with the following basic steps to completely remove a Django app.
# Remove Django migrations.
DELETE FROM `django_migrations` WHERE `app` = 'my_app';
# Get rid of permissions and content types.
DELETE FROM `auth_permission` WHERE `content_type_id` in (SELECT `id` FROM `django_content_type` WHERE `app_label` = 'my_app');
# Get rid of admin changes.
DELETE FROM `django_admin_log` WHERE `content_type_id` in (SELECT `id` FROM `django_content_type` WHERE `app_label` = 'my_app');
# Finally, delete the content type.
DELETE FROM `django_content_type` WHERE `app_label` = 'my_app';
If you’re in the unfortunate situation of removing a third-party application that has models, I’ve found it easiest to replace steps 2 - 3 & 5 - 6 with standard drop table calls:
DROP TABLE `my_app_some_model`;
DROP TABLE `my_app_other_model`;
I’m fairly certain I got the initial idea for this from somewhere else, but unfortunately I didn’t save the original source. It has evolved over the past years to be easier to run (e.g. the sub-queries) and I have used it > 5 times without issues. It probably should be abstracted into a management command, but I never got around to it.
I’m still surprised there isn’t (to my knowledge) an easier way to do this within Django!