Skip to main content

Disable Django database writes.

Project description pre-commit

Disable Django database writes.


Python 3.6 to 3.9 supported.

Django 2.2 to 3.2 supported.

Are your tests slow? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.


Install with pip:

python -m pip install django-read-only

Then add to your installed apps:



In your settings file, set DJANGO_READ_ONLY to True and all data modification queries will cause an exception:

$ DJANGO_READ_ONLY=1 python shell
>>> User.objects.create_user(username="hacker", password="hunter2")

For convenience, you can also control this with the DJANGO_READ_ONLY environment variable, which will count as True if set to anything but the empty string. The setting takes precedence over the environment variable.

During a session with DJANGO_READ_ONLY set on, you can re-enable writes by calling enable_writes():

>>> import django_read_only
>>> django_read_only.enable_writes()

Writes can be disabled with disable_writes():

>>> django_read_only.disable_writes()

To temporarily allow writes, use the temp_writes() context manager / decorator:

>>> with django_read_only.temp_writes():
...     User.objects.create_user(...)

Note that writes being enabled/disabled is global state, affecting all threads and asynchronous coroutines.

How it Works

The most accurate way to prevent writes is to connect as a separate database user with only read permission. However, this has limitations - Django doesn’t support modifying the DATABASES setting live, so sessions would not be able to temporarily allow writes.

Instead, django-read-only uses always installed database instrumentation to inspect executed queries and only allow those which look like reads. It uses a “fail closed” philosophy, so anything unknown will fail, which should be fairly reasonable.

Because django-read-only uses Django database instrumentation, it cannot block queries running through the underlying database connection (accesses through django.db.connection.connection), and it cannot filter operations within stored procedures (which use connection.callproc()). These are very rare in practice though, so django-read-only’s method works well for most projects.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-read-only-1.4.0.tar.gz (6.7 kB view hashes)

Uploaded source

Built Distribution

django_read_only-1.4.0-py3-none-any.whl (6.0 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page