Registry / web-framework / django-cleanup

django-cleanup

JSON →
library9.0.0pypypi✓ verified 23d ago

django-cleanup is a lightweight Django library that automatically deletes files associated with `FileField` and `ImageField` when their corresponding model instances are deleted or when the file itself is changed. This prevents orphaned files from cluttering storage. It integrates seamlessly into existing Django projects with minimal configuration, supporting bulk deletions and various storage backends (e.g., local filesystem, Amazon S3). The current version is 9.0.0, released on September 18, 2024, and it aims to maintain compatibility with currently supported Django and Python versions.

pip install django-cleanup
INSTALL
IMPORT
SIG · DJANGO-CLEANUP
D
django-cleanup
web-frameworkpythonv9.0.0
Install
1.5s avg
Import
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v9.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.5s · import 0.000s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

django_cleanup
INSTALLED_APPS = ['...', 'django_cleanup']
INSTALLED_APPS = ['...', 'django_cleanup']

After installation, add `django_cleanup.apps.CleanupConfig` to your `INSTALLED_APPS`. `django-cleanup` will then automatically handle file deletion for any `FileField` or `ImageField` on your models when a model instance is deleted, or when a file in a field is replaced. No additional code is needed in your models or views for basic functionality.

import os import django from django.conf import settings from django.db import models os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') # Minimal Django settings for demonstration if not settings.configured: settings.configure( INSTALLED_APPS=[ 'django.contrib.auth', 'django.contrib.contenttypes', 'django_cleanup.apps.CleanupConfig', 'myapp' # Your app where models reside ], DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}}, MEDIA_ROOT=os.path.join(os.getcwd(), 'media_test'), DEFAULT_AUTO_FIELD='django.db.models.AutoField', ) django.setup() # Create a dummy app to hold models class MyAppConfig(django.apps.AppConfig): name = 'myapp' label = 'myapp' # Add dummy app to apps registry if not django.apps.apps.get_app_config('myapp'): django.apps.apps.populate(settings.INSTALLED_APPS) # Define a simple model with a FileField class MyModel(models.Model): name = models.CharField(max_length=100) image = models.ImageField(upload_to='images') def __str__(self): return self.name # Ensure media directory exists for testing os.makedirs(settings.MEDIA_ROOT, exist_ok=True) # Simulate model usage print(f"Media root: {settings.MEDIA_ROOT}") # 1. Create instance and save a dummy file instance = MyModel(name='Test Item') # Create a dummy image file dummy_image_path = os.path.join(settings.MEDIA_ROOT, 'images', 'test_image.jpg') os.makedirs(os.path.dirname(dummy_image_path), exist_ok=True) with open(dummy_image_path, 'w') as f: f.write('dummy image content') instance.image.name = 'images/test_image.jpg' instance.save() print(f"File exists after creation: {os.path.exists(dummy_image_path)}") # 2. Update instance with a new file (old one should be deleted) new_dummy_image_path = os.path.join(settings.MEDIA_ROOT, 'images', 'new_test_image.jpg') with open(new_dummy_image_path, 'w') as f: f.write('new dummy image content') old_image_name = instance.image.name instance.image.name = 'images/new_test_image.jpg' instance.save() print(f"Old file '{old_image_name}' exists after update: {os.path.exists(os.path.join(settings.MEDIA_ROOT, old_image_name))}") print(f"New file exists after update: {os.path.exists(new_dummy_image_path)}") # 3. Delete instance (associated file should be deleted) instance_pk = instance.pk instance.delete() print(f"New file exists after instance deletion: {os.path.exists(new_dummy_image_path)}") # Clean up test media directory (optional) import shutil shutil.rmtree(settings.MEDIA_ROOT) print("Cleaned up media_test directory.")
Debug
Known issues
gotchaThe `django_cleanup.apps.CleanupConfig` must be placed *last* in your `INSTALLED_APPS` setting. This ensures that it can correctly discover all `FileField`s across all your applications and that file deletion integrity within transactions is maintained, even if other apps' signal handlers raise exceptions.
fix
Ensure 'django_cleanup.apps.CleanupConfig' is the last entry in `INSTALLED_APPS` in your `settings.py`.
affects: All versions
gotchaIf your project uses a database that does not support transactions, or if a transaction rolls back, files *may* be lost without their corresponding model instance being fully deleted or updated. While `django-cleanup` mitigates this using `post_save` and `post_delete` signals, it's a known limitation to be aware of if your database setup is unusual.
fix
Use a transactional database. If not possible, ensure robust backup strategies and understand the implications of rollbacks on file integrity. Consider alternative manual cleanup solutions if this is a critical concern.
affects: All versions
gotcha`django-cleanup` relies on Django's application registry to discover models and their `FileField`s. If your models are not properly loaded (e.g., if they are not defined or imported in your app's `models.py` or `models/__init__.py`), `django-cleanup` may not be able to discover them and thus won't remove files as expected.
fix
Ensure all models within your Django apps are correctly defined or imported within their respective `models.py` or `models/__init__.py` files to guarantee they are registered with Django's ORM.
affects: All versions
gotchaFiles that are explicitly set as a `FileField`'s `default` value will *not* be deleted by `django-cleanup`. This is by design to prevent accidental deletion of common default files that might be referenced by many instances.
fix
Be aware that default files are not managed. If a file associated with a `FileField` needs to be cleaned up, it should not be set as the field's `default`.
affects: All versions
Upgrade
Version history
9.0.0latest on PyPI · released Sep 18, 2024
Audit
Dependencies
DjangorequiredCore framework dependency, follows Django's supported versions.
pythonrequiredRuntime environment
Agent activity
11 hits · last 30 days
node
10
Resources
django-cleanup — pip install django-cleanup · libregistry