Give AlbumentationsX a star on GitHub — it powers this leaderboard

Star on GitHub

django-redis

Full featured redis cache backend for Django.

Rank: #1285Downloads: 8,630,040 (30 days)Stars: 3,056Forks: 444

Description

==============================
Redis cache backend for Django
==============================

.. image:: https://jazzband.co/static/img/badge.svg
    :target: https://jazzband.co/
    :alt: Jazzband

.. image:: https://github.com/jazzband/django-redis/actions/workflows/ci.yml/badge.svg
   :target: https://github.com/jazzband/django-redis/actions/workflows/ci.yml
   :alt: GitHub Actions

.. image:: https://codecov.io/gh/jazzband/django-redis/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/jazzband/django-redis
   :alt: Coverage

.. image:: https://img.shields.io/pypi/v/django-redis.svg?style=flat
    :target: https://pypi.org/project/django-redis/

This is a `Jazzband <https://jazzband.co>`_ project. By contributing you agree
to abide by the `Contributor Code of Conduct
<https://jazzband.co/about/conduct>`_ and follow the `guidelines
<https://jazzband.co/about/guidelines>`_.

Introduction
------------

django-redis is a BSD licensed, full featured Redis cache and session backend
for Django.

Why use django-redis?
~~~~~~~~~~~~~~~~~~~~~

- Uses native redis-py url notation connection strings
- Pluggable clients
- Pluggable parsers
- Pluggable serializers
- Primary/secondary support in the default client
- Comprehensive test suite
- Used in production in several projects as cache and session storage
- Supports infinite timeouts
- Facilities for raw access to Redis client/connection pool
- Highly configurable (can emulate memcached exception behavior, for example)
- Unix sockets supported by default

Requirements
~~~~~~~~~~~~

- `Python`_ 3.9+
- `Django`_ 4.2+
- `redis-py`_ 4.0.2+
- `Redis server`_ 2.8+

.. _Python: https://www.python.org/downloads/
.. _Django: https://www.djangoproject.com/download/
.. _redis-py: https://pypi.org/project/redis/
.. _Redis server: https://redis.io/download

User guide
----------

Installation
~~~~~~~~~~~~

Install with pip:

.. code-block:: console

    $ python -m pip install django-redis

Configure as cache backend
~~~~~~~~~~~~~~~~~~~~~~~~~~

To start using django-redis, you should change your Django cache settings to
something like:

.. code-block:: python

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
    }

django-redis uses the redis-py native URL notation for connection strings, it
allows better interoperability and has a connection string in more "standard"
way. Some examples:

- ``redis://[[username]:[password]]@localhost:6379/0``
- ``rediss://[[username]:[password]]@localhost:6379/0``
- ``unix://[[username]:[password]]@/path/to/socket.sock?db=0``

Three URL schemes are supported:

- ``redis://``: creates a normal TCP socket connection
- ``rediss://``: creates a SSL wrapped TCP socket connection
- ``unix://`` creates a Unix Domain Socket connection

There are several ways to specify a database number:

- A ``db`` querystring option, e.g. ``redis://localhost?db=0``
- If using the ``redis://`` scheme, the path argument of the URL, e.g.
  ``redis://localhost/0``

When using `Redis' ACLs <https://redis.io/topics/acl>`_, you will need to add the
username to the URL (and provide the password with the Cache ``OPTIONS``).
The login for the user ``django`` would look like this:

.. code-block:: python

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://django@localhost:6379/0",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "PASSWORD": "mysecret"
            }
        }
    }

An alternative would be write both username and password into the URL:

.. code-block:: python

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://django:mysecret@localhost:6379/0",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
    }

In some circumstances the password you should use to connect Redis
is not URL-safe, in this case you can escape it or just use the
convenience option in ``OPTIONS`` dict:

.. code-block:: python

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "PASSWORD": "mysecret"
            }
        }
    }

Take care, that this option does not overwrites the password in the uri, so if
you have set the password in the uri, this settings will be ignored.

Configure as session backend
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Django can by default use any cache backend as session backend and you benefit
from that by using django-redis as backend for session storage without
installing any additional backends:

.. code-block:: python

    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
    SESSION_CACHE_ALIAS = "default"

Testing with django-redis
~~~~~~~~~~~~~~~~~~~~~~~~~

django-redis supports customizing the underlying Redis client (see "Pluggable
clients"). This can be used for testing purposes.

In case you want to flush all data from the cache after a test, add the
following lines to your test class:

.. code-block:: python

    from django_redis import get_redis_connection

    def tearDown(self):
        get_redis_connection("default").flushall()

Advanced usage
--------------

Pickle version
~~~~~~~~~~~~~~

For almost all values, django-redis uses pickle to serialize objects.

The ``pickle.DEFAULT_PROTOCOL`` version of pickle is used by default to ensure safe upgrades and compatibility across Python versions.
If you want set a concrete version, you can do it, using ``PICKLE_VERSION`` option:

.. code-block:: python

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "PICKLE_VERSION": -1  # Will use highest protocol version available
            }
        }
    }

Socket timeout
~~~~~~~~~~~~~~

Socket timeout can be set using ``SOCKET_TIMEOUT`` and
``SOCKET_CONNECT_TIMEOUT`` options:

.. code-block:: python

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "SOCKET_CONNECT_TIMEOUT": 5,  # seconds
                "SOCKET_TIMEOUT": 5,  # seconds
            }
        }
    }

``SOCKET_CONNECT_TIMEOUT`` is the timeout for the connection to be established
and ``SOCKET_TIMEOUT`` is the timeout for read and write operations after the
connection is established.

Compression support
~~~~~~~~~~~~~~~~~~~

django-redis comes with compression support out of the box, but is deactivated
by default. You can activate it setting up a concrete backend:

.. code-block:: python

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor",
            }
        }
    }

Let see an example, of how make it work with *lzma* compression format:

.. code-block:: python

    import lzma

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "COMPRESSOR": "django_redis.compressors.lzma.LzmaCompressor",
            }
        }
    }

*Lz4* compression support (requires the lz4 library):

.. code-block:: python

    import lz4

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "COMPRESSOR": "django_redis.compressors.lz4.Lz4Compressor",
            }
        }
    }

*Zstandard (zstd)* compression support (requires the pyzstd library):

.. code-block:: python

    import pyzstd

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "COMPRESSOR": "django_redis.compressors.zstd.ZStdCompressor",
            }
        }
    }

*Gzip* compression support:

.. code-block:: python

    import gzip

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "COMPRESSOR": "django_redis.compressors.gzip.GzipCompressor",
            }
        }
    }

Memcached exceptions behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In some situations, when Redis is only used for cache, you do not want
exceptions when Redis is down. This is default behavior in the memcached
backend and it can be emulated in django-redis.

For setup memcached like behaviour (ignore connection exceptions), you should
set ``IGNORE_EXCEPTIONS`` settings on your cache configuration:

.. code-block:: python

    CACHES = {
        "default": {
            # ...
            "OPTIONS": {
                "IGNORE_EXCEPTIONS": True,
            }
        }
    }

Also, you can apply the same settings to all configured caches, you can set the global flag in
your settings:

.. code-block:: python

    DJANGO_REDIS_IGNORE_EXCEPTIONS = True

Log Ignored Exceptions
~~~~~~~~~~~~~~~~~~~~~~

When ignoring exceptions with ``IGNORE_EXCEPTIONS`` or
``DJANGO_REDIS_IGNORE_EXCEPTIONS``, you may optionally log exceptions using the
global variable ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` in your settings file::

    DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True

If you wish to specify the logger in which the exceptions are output, simply
set the global variable ``DJANGO_REDIS_LOGGER`` to the string name and/or path
of the desired logger. This will default to ``__name__`` if no logger is
specified and ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` is ``True``::

    DJANGO_REDIS_LOGGER = 'some.specified.logger'

Infinite timeout
~~~~~~~~~~~~~~~~

django-redis comes with infinite timeouts support out of the box. And it
behaves in same way as django backend contract specifies:

- ``timeout=0`` expires the value immediately.
- ``timeout=None`` infinite timeout

.. code-block:: python

    cache.set("key", "value", timeout=None)

Get ttl (time-to-live) from key