skip to navigation
skip to content

Not Logged In

django-db-readonly 0.3.1

Add a global database read-only setting.

## About

An way to globally disable writes to your database. This works by
inserting a cursor wrapper between Django's `CursorWrapper` and
the database connection's cursor wrapper. So many cursor wrappers!

## Installation

I uploaded it to [PyPi][pypi], so you can grab it there if you'd like with

pip install django-db-readonly

or install with pip the git address:

pip install

You're choice. Then add `readonly` to your `INSTALLED_APPS`.

    # ...
    # ...

## Usage

You shouldn't notice this at all, _unless_ you add the following line
to your ``:

# Set to False to allow writes

When you do this, any write action to your databases will generate an
exception. You should catch this exception and deal with it somehow. Or
let Django display an [error 500 page][error500]. The exception you will
want to catch is `readonly.exceptions.DatabaseWriteDenied` which inherits
from `django.db.utils.DatabaseError`.

There is also a middleware class that will handle the exceptions and attempt
to handle them smartly. Add the following line in your ``:

    # ...
    # ...

This will then enable the middleware which will catch `DatabaseWriteDenied`
exceptions. If the request is a POST request, we will redirect the user to the
same URL, but as a GET request. If the request is not a POST (ie. a GET), we
will just display a `HttpResponse` with text telling the user the site
is in read-only mode.

In addition, the middleware class can add an error-type message using the
`django.contrib.messages` module. Add:

# Enable

to your `` and then on POST requests that generate a
`DatabaseWriteDenied` exception, we will add an error message informing the
user that the site is in read-only mode.

For additional messaging, there is a context processor that adds
`SITE_READ_ONLY` into the context. Add the following line in your ``:

    # ...
    # ...

And use it as you would any boolean in the template, e.g. `{% if SITE_READ_ONLY
%} We're down for maintenance. {% endif %}`

## Testing

There aren't any tests included, yet. Run it at your own peril.

## Caveats

This will work with [Django Debug Toolbar][ddt]. In fact, I was inspired
by [DDT's sql panel][sql-panel] when writing this app.

However, in order for both DDT _and_ django-db-readonly to work, you need
to make sure that you have `readonly` before `debug_toolbar` in your
`INSTALLED_APPS`. Otherwise, you are responsible for debugging what is
going on. Of course, I'm not sure why you'd be running DDT in production
and running django-db-readonly in development, but whatever, I'm not you.

More generally, if you have any other apps that modifies either
`django.db.backends.util.CursorWrapper` or
`django.db.backends.util.CursorDebugWrapper`, you need to make sure
that `readonly` is placed _before_ of those apps in `INSTALLED_APPS`.

## The Nitty Gritty

How does this do what it does? Well, django-db-readonly sits between
Django's own cursor wrapper at `django.db.backends.util.CursorWrapper` and
the database specific cursor at `django.db.backends.*.base.*CursorWrapper`.
It overrides two specific methods: `execute` and `executemany`. If the
site is in read-only mode, then the SQL is examined to see if it
contains any write actions (defined in
`readonly.ReadOnlyCursorWrapper.SQL_WRITE_BLACKLIST`). If a write is
detected, an exception is raised.

File Type Py Version Uploaded on Size
django-db-readonly-0.3.1.tar.gz (md5) Source 2013-01-16 5KB
  • Downloads (All Versions):
  • 16 downloads in the last day
  • 141 downloads in the last week
  • 732 downloads in the last month