1Metadata-Version: 2.1 2Name: django-redis 3Version: 5.1.0 4Summary: Full featured redis cache backend for Django. 5Home-page: https://github.com/jazzband/django-redis 6Author: Andrei Antoukh 7Author-email: niwi@niwi.nz 8License: BSD-3-Clause 9Platform: UNKNOWN 10Classifier: Development Status :: 5 - Production/Stable 11Classifier: Environment :: Web Environment 12Classifier: Framework :: Django 13Classifier: Framework :: Django :: 2.2 14Classifier: Framework :: Django :: 3.1 15Classifier: Framework :: Django :: 3.2 16Classifier: Intended Audience :: Developers 17Classifier: License :: OSI Approved :: BSD License 18Classifier: Operating System :: OS Independent 19Classifier: Programming Language :: Python 20Classifier: Programming Language :: Python :: 3 21Classifier: Programming Language :: Python :: 3 :: Only 22Classifier: Programming Language :: Python :: 3.6 23Classifier: Programming Language :: Python :: 3.7 24Classifier: Programming Language :: Python :: 3.8 25Classifier: Programming Language :: Python :: 3.9 26Classifier: Programming Language :: Python :: 3.10 27Classifier: Topic :: Software Development :: Libraries 28Classifier: Topic :: Utilities 29Requires-Python: >=3.6 30Description-Content-Type: text/x-rst 31Provides-Extra: hiredis 32License-File: LICENSE 33License-File: AUTHORS.rst 34 35============================== 36Redis cache backend for Django 37============================== 38 39.. image:: https://jazzband.co/static/img/badge.svg 40 :target: https://jazzband.co/ 41 :alt: Jazzband 42 43.. image:: https://github.com/jazzband/django-redis/actions/workflows/ci.yml/badge.svg 44 :target: https://github.com/jazzband/django-redis/actions/workflows/ci.yml 45 :alt: GitHub Actions 46 47.. image:: https://codecov.io/gh/jazzband/django-redis/branch/master/graph/badge.svg 48 :target: https://codecov.io/gh/jazzband/django-redis 49 :alt: Coverage 50 51.. image:: https://img.shields.io/pypi/v/django-redis.svg?style=flat 52 :target: https://pypi.org/project/django-redis/ 53 54This is a `Jazzband <https://jazzband.co>`_ project. By contributing you agree 55to abide by the `Contributor Code of Conduct 56<https://jazzband.co/about/conduct>`_ and follow the `guidelines 57<https://jazzband.co/about/guidelines>`_. 58 59Introduction 60------------ 61 62django-redis is a BSD licensed, full featured Redis cache and session backend 63for Django. 64 65Why use django-redis? 66~~~~~~~~~~~~~~~~~~~~~ 67 68- Uses native redis-py url notation connection strings 69- Pluggable clients 70- Pluggable parsers 71- Pluggable serializers 72- Primary/secondary support in the default client 73- Comprehensive test suite 74- Used in production in several projects as cache and session storage 75- Supports infinite timeouts 76- Facilities for raw access to Redis client/connection pool 77- Highly configurable (can emulate memcached exception behavior, for example) 78- Unix sockets supported by default 79 80Requirements 81~~~~~~~~~~~~ 82 83- `Python`_ 3.6+ 84- `Django`_ 2.2+ 85- `redis-py`_ 3.0+ 86- `Redis server`_ 2.8+ 87 88.. _Python: https://www.python.org/downloads/ 89.. _Django: https://www.djangoproject.com/download/ 90.. _redis-py: https://pypi.org/project/redis/ 91.. _Redis server: https://redis.io/download 92 93User guide 94---------- 95 96Installation 97~~~~~~~~~~~~ 98 99Install with pip: 100 101.. code-block:: console 102 103 $ python -m pip install django-redis 104 105Configure as cache backend 106~~~~~~~~~~~~~~~~~~~~~~~~~~ 107 108To start using django-redis, you should change your Django cache settings to 109something like: 110 111.. code-block:: python 112 113 CACHES = { 114 "default": { 115 "BACKEND": "django_redis.cache.RedisCache", 116 "LOCATION": "redis://127.0.0.1:6379/1", 117 "OPTIONS": { 118 "CLIENT_CLASS": "django_redis.client.DefaultClient", 119 } 120 } 121 } 122 123django-redis uses the redis-py native URL notation for connection strings, it 124allows better interoperability and has a connection string in more "standard" 125way. Some examples: 126 127- ``redis://[[username]:[password]]@localhost:6379/0`` 128- ``rediss://[[username]:[password]]@localhost:6379/0`` 129- ``unix://[[username]:[password]]@/path/to/socket.sock?db=0`` 130 131Three URL schemes are supported: 132 133- ``redis://``: creates a normal TCP socket connection 134- ``rediss://``: creates a SSL wrapped TCP socket connection 135- ``unix://`` creates a Unix Domain Socket connection 136 137There are several ways to specify a database number: 138 139- A ``db`` querystring option, e.g. ``redis://localhost?db=0`` 140- If using the ``redis://`` scheme, the path argument of the URL, e.g. 141 ``redis://localhost/0`` 142 143When using `Redis' ACLs <https://redis.io/topics/acl>`_, you will need to add the 144username to the URL (and provide the password with the Cache ``OPTIONS``). 145The login for the user ``django`` would look like this: 146 147.. code-block:: python 148 149 CACHES = { 150 "default": { 151 "BACKEND": "django_redis.cache.RedisCache", 152 "LOCATION": "redis://django@localhost:6379/0", 153 "OPTIONS": { 154 "CLIENT_CLASS": "django_redis.client.DefaultClient", 155 "PASSWORD": "mysecret" 156 } 157 } 158 } 159 160An alternative would be write both username and password into the URL: 161 162.. code-block:: python 163 164 CACHES = { 165 "default": { 166 "BACKEND": "django_redis.cache.RedisCache", 167 "LOCATION": "redis://django:mysecret@localhost:6379/0", 168 "OPTIONS": { 169 "CLIENT_CLASS": "django_redis.client.DefaultClient", 170 } 171 } 172 } 173 174In some circumstances the password you should use to connect Redis 175is not URL-safe, in this case you can escape it or just use the 176convenience option in ``OPTIONS`` dict: 177 178.. code-block:: python 179 180 CACHES = { 181 "default": { 182 "BACKEND": "django_redis.cache.RedisCache", 183 "LOCATION": "redis://127.0.0.1:6379/1", 184 "OPTIONS": { 185 "CLIENT_CLASS": "django_redis.client.DefaultClient", 186 "PASSWORD": "mysecret" 187 } 188 } 189 } 190 191Take care, that this option does not overwrites the password in the uri, so if 192you have set the password in the uri, this settings will be ignored. 193 194Configure as session backend 195~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 197Django can by default use any cache backend as session backend and you benefit 198from that by using django-redis as backend for session storage without 199installing any additional backends: 200 201.. code-block:: python 202 203 SESSION_ENGINE = "django.contrib.sessions.backends.cache" 204 SESSION_CACHE_ALIAS = "default" 205 206Testing with django-redis 207~~~~~~~~~~~~~~~~~~~~~~~~~ 208 209django-redis supports customizing the underlying Redis client (see "Pluggable 210clients"). This can be used for testing purposes. 211 212In case you want to flush all data from the cache after a test, add the 213following lines to your test class: 214 215.. code-block:: python 216 217 from django_redis import get_redis_connection 218 219 def tearDown(self): 220 get_redis_connection("default").flushall() 221 222Advanced usage 223-------------- 224 225Pickle version 226~~~~~~~~~~~~~~ 227 228For almost all values, django-redis uses pickle to serialize objects. 229 230The ``pickle.DEFAULT_PROTOCOL`` version of pickle is used by default to ensure safe upgrades and compatibility across Python versions. 231If you want set a concrete version, you can do it, using ``PICKLE_VERSION`` option: 232 233.. code-block:: python 234 235 CACHES = { 236 "default": { 237 # ... 238 "OPTIONS": { 239 "PICKLE_VERSION": -1 # Will use highest protocol version available 240 } 241 } 242 } 243 244Socket timeout 245~~~~~~~~~~~~~~ 246 247Socket timeout can be set using ``SOCKET_TIMEOUT`` and 248``SOCKET_CONNECT_TIMEOUT`` options: 249 250.. code-block:: python 251 252 CACHES = { 253 "default": { 254 # ... 255 "OPTIONS": { 256 "SOCKET_CONNECT_TIMEOUT": 5, # seconds 257 "SOCKET_TIMEOUT": 5, # seconds 258 } 259 } 260 } 261 262``SOCKET_CONNECT_TIMEOUT`` is the timeout for the connection to be established 263and ``SOCKET_TIMEOUT`` is the timeout for read and write operations after the 264connection is established. 265 266Compression support 267~~~~~~~~~~~~~~~~~~~ 268 269django-redis comes with compression support out of the box, but is deactivated 270by default. You can activate it setting up a concrete backend: 271 272.. code-block:: python 273 274 CACHES = { 275 "default": { 276 # ... 277 "OPTIONS": { 278 "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor", 279 } 280 } 281 } 282 283Let see an example, of how make it work with *lzma* compression format: 284 285.. code-block:: python 286 287 import lzma 288 289 CACHES = { 290 "default": { 291 # ... 292 "OPTIONS": { 293 "COMPRESSOR": "django_redis.compressors.lzma.LzmaCompressor", 294 } 295 } 296 } 297 298*Lz4* compression support (requires the lz4 library): 299 300.. code-block:: python 301 302 import lz4 303 304 CACHES = { 305 "default": { 306 # ... 307 "OPTIONS": { 308 "COMPRESSOR": "django_redis.compressors.lz4.Lz4Compressor", 309 } 310 } 311 } 312 313*Zstandard (zstd)* compression support (requires the pyzstd library): 314 315.. code-block:: python 316 317 import pyzstd 318 319 CACHES = { 320 "default": { 321 # ... 322 "OPTIONS": { 323 "COMPRESSOR": "django_redis.compressors.zstd.ZStdCompressor", 324 } 325 } 326 } 327 328Memcached exceptions behavior 329~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 330 331In some situations, when Redis is only used for cache, you do not want 332exceptions when Redis is down. This is default behavior in the memcached 333backend and it can be emulated in django-redis. 334 335For setup memcached like behaviour (ignore connection exceptions), you should 336set ``IGNORE_EXCEPTIONS`` settings on your cache configuration: 337 338.. code-block:: python 339 340 CACHES = { 341 "default": { 342 # ... 343 "OPTIONS": { 344 "IGNORE_EXCEPTIONS": True, 345 } 346 } 347 } 348 349Also, you can apply the same settings to all configured caches, you can set the global flag in 350your settings: 351 352.. code-block:: python 353 354 DJANGO_REDIS_IGNORE_EXCEPTIONS = True 355 356Log Ignored Exceptions 357~~~~~~~~~~~~~~~~~~~~~~ 358 359When ignoring exceptions with ``IGNORE_EXCEPTIONS`` or 360``DJANGO_REDIS_IGNORE_EXCEPTIONS``, you may optionally log exceptions using the 361global variable ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` in your settings file:: 362 363 DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True 364 365If you wish to specify the logger in which the exceptions are output, simply 366set the global variable ``DJANGO_REDIS_LOGGER`` to the string name and/or path 367of the desired logger. This will default to ``__name__`` if no logger is 368specified and ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` is ``True``:: 369 370 DJANGO_REDIS_LOGGER = 'some.specified.logger' 371 372Infinite timeout 373~~~~~~~~~~~~~~~~ 374 375django-redis comes with infinite timeouts support out of the box. And it 376behaves in same way as django backend contract specifies: 377 378- ``timeout=0`` expires the value immediately. 379- ``timeout=None`` infinite timeout 380 381.. code-block:: python 382 383 cache.set("key", "value", timeout=None) 384 385Get ttl (time-to-live) from key 386~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 387 388With Redis, you can access to ttl of any stored key, for it, django-redis 389exposes ``ttl`` function. 390 391It returns: 392 393- 0 if key does not exists (or already expired). 394- None for keys that exists but does not have any expiration. 395- ttl value for any volatile key (any key that has expiration). 396 397.. code-block:: pycon 398 399 >>> from django.core.cache import cache 400 >>> cache.set("foo", "value", timeout=25) 401 >>> cache.ttl("foo") 402 25 403 >>> cache.ttl("not-existent") 404 0 405 406With Redis, you can access to ttl of any stored key in milliseconds, for it, django-redis 407exposes ``pttl`` function. 408 409.. code-block:: pycon 410 411 >>> from django.core.cache import cache 412 >>> cache.set("foo", "value", timeout=25) 413 >>> cache.pttl("foo") 414 25000 415 >>> cache.pttl("not-existent") 416 0 417 418Expire & Persist 419~~~~~~~~~~~~~~~~ 420 421Additionally to the simple ttl query, you can send persist a concrete key or 422specify a new expiration timeout using the ``persist`` and ``expire`` methods: 423 424.. code-block:: pycon 425 426 >>> cache.set("foo", "bar", timeout=22) 427 >>> cache.ttl("foo") 428 22 429 >>> cache.persist("foo") 430 True 431 >>> cache.ttl("foo") 432 None 433 434.. code-block:: pycon 435 436 >>> cache.set("foo", "bar", timeout=22) 437 >>> cache.expire("foo", timeout=5) 438 True 439 >>> cache.ttl("foo") 440 5 441 442The ``expire_at`` method can be used to make the key expire at a specific moment in time. 443 444.. code-block:: pycon 445 446 >>> cache.set("foo", "bar", timeout=22) 447 >>> cache.expire_at("foo", datetime.now() + timedelta(hours=1)) 448 True 449 >>> cache.ttl("foo") 450 3600 451 452The ``pexpire_at`` method can be used to make the key expire at a specific moment in time with milliseconds precision: 453 454.. code-block:: pycon 455 456 >>> cache.set("foo", "bar", timeout=22) 457 >>> cache.pexpire_at("foo", datetime.now() + timedelta(milliseconds=900, hours=1)) 458 True 459 >>> cache.ttl("foo") 460 3601 461 >>> cache.pttl("foo") 462 3600900 463 464The ``pexpire`` method can be used to provide millisecond precision: 465 466.. code-block:: pycon 467 468 >>> cache.set("foo", "bar", timeout=22) 469 >>> cache.pexpire("foo", timeout=5500) 470 True 471 >>> cache.pttl("foo") 472 5500 473 474Locks 475~~~~~ 476 477It also supports the Redis ability to create Redis distributed named locks. The 478Lock interface is identical to the ``threading.Lock`` so you can use it as 479replacement. 480 481.. code-block:: python 482 483 with cache.lock("somekey"): 484 do_some_thing() 485 486Scan & Delete keys in bulk 487~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 489django-redis comes with some additional methods that help with searching or 490deleting keys using glob patterns. 491 492.. code-block:: pycon 493 494 >>> from django.core.cache import cache 495 >>> cache.keys("foo_*") 496 ["foo_1", "foo_2"] 497 498A simple search like this will return all matched values. In databases with a 499large number of keys this isn't suitable method. Instead, you can use the 500``iter_keys`` function that works like the ``keys`` function but uses Redis 501server side cursors. Calling ``iter_keys`` will return a generator that you can 502then iterate over efficiently. 503 504.. code-block:: pycon 505 506 >>> from django.core.cache import cache 507 >>> cache.iter_keys("foo_*") 508 <generator object algo at 0x7ffa9c2713a8> 509 >>> next(cache.iter_keys("foo_*")) 510 "foo_1" 511 512For deleting keys, you should use ``delete_pattern`` which has the same glob 513pattern syntax as the ``keys`` function and returns the number of deleted keys. 514 515.. code-block:: pycon 516 517 >>> from django.core.cache import cache 518 >>> cache.delete_pattern("foo_*") 519 520Redis native commands 521~~~~~~~~~~~~~~~~~~~~~ 522 523django-redis has limited support for some Redis atomic operations, such as the 524commands ``SETNX`` and ``INCR``. 525 526You can use the ``SETNX`` command through the backend ``set()`` method with the 527``nx`` parameter: 528 529.. code-block:: pycon 530 531 >>> from django.core.cache import cache 532 >>> cache.set("key", "value1", nx=True) 533 True 534 >>> cache.set("key", "value2", nx=True) 535 False 536 >>> cache.get("key") 537 "value1" 538 539Also, the ``incr`` and ``decr`` methods use Redis atomic operations when the 540value that a key contains is suitable for it. 541 542Raw client access 543~~~~~~~~~~~~~~~~~ 544 545In some situations your application requires access to a raw Redis client to 546use some advanced features that aren't exposed by the Django cache interface. 547To avoid storing another setting for creating a raw connection, django-redis 548exposes functions with which you can obtain a raw client reusing the cache 549connection string: ``get_redis_connection(alias)``. 550 551.. code-block:: pycon 552 553 >>> from django_redis import get_redis_connection 554 >>> con = get_redis_connection("default") 555 >>> con 556 <redis.client.Redis object at 0x2dc4510> 557 558WARNING: Not all pluggable clients support this feature. 559 560Connection pools 561~~~~~~~~~~~~~~~~ 562 563Behind the scenes, django-redis uses the underlying redis-py connection pool 564implementation, and exposes a simple way to configure it. Alternatively, you 565can directly customize a connection/connection pool creation for a backend. 566 567The default redis-py behavior is to not close connections, recycling them when 568possible. 569 570Configure default connection pool 571^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 572 573The default connection pool is simple. For example, you can customize the 574maximum number of connections in the pool by setting ``CONNECTION_POOL_KWARGS`` 575in the ``CACHES`` setting: 576 577.. code-block:: python 578 579 CACHES = { 580 "default": { 581 "BACKEND": "django_redis.cache.RedisCache", 582 # ... 583 "OPTIONS": { 584 "CONNECTION_POOL_KWARGS": {"max_connections": 100} 585 } 586 } 587 } 588 589You can verify how many connections the pool has opened with the following 590snippet: 591 592.. code-block:: python 593 594 from django_redis import get_redis_connection 595 596 r = get_redis_connection("default") # Use the name you have defined for Redis in settings.CACHES 597 connection_pool = r.connection_pool 598 print("Created connections so far: %d" % connection_pool._created_connections) 599 600Since the default connection pool passes all keyword arguments it doesn't use 601to its connections, you can also customize the connections that the pool makes 602by adding those options to ``CONNECTION_POOL_KWARGS``: 603 604.. code-block:: python 605 606 CACHES = { 607 "default": { 608 # ... 609 "OPTIONS": { 610 "CONNECTION_POOL_KWARGS": {"max_connections": 100, "retry_on_timeout": True} 611 } 612 } 613 } 614 615Use your own connection pool subclass 616^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 617 618Sometimes you want to use your own subclass of the connection pool. This is 619possible with django-redis using the ``CONNECTION_POOL_CLASS`` parameter in the 620backend options. 621 622.. code-block:: python 623 624 from redis.connection import ConnectionPool 625 626 class MyOwnPool(ConnectionPool): 627 # Just doing nothing, only for example purpose 628 pass 629 630.. code-block:: python 631 632 # Omitting all backend declaration boilerplate code. 633 634 "OPTIONS": { 635 "CONNECTION_POOL_CLASS": "myproj.mypool.MyOwnPool", 636 } 637 638Customize connection factory 639^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 640 641If none of the previous methods satisfies you, you can get in the middle of the 642django-redis connection factory process and customize or completely rewrite it. 643 644By default, django-redis creates connections through the 645``django_redis.pool.ConnectionFactory`` class that is specified in the global 646Django setting ``DJANGO_REDIS_CONNECTION_FACTORY``. 647 648.. code-block:: python 649 650 class ConnectionFactory(object): 651 def get_connection_pool(self, params: dict): 652 # Given connection parameters in the `params` argument, return new 653 # connection pool. It should be overwritten if you want do 654 # something before/after creating the connection pool, or return 655 # your own connection pool. 656 pass 657 658 def get_connection(self, params: dict): 659 # Given connection parameters in the `params` argument, return a 660 # new connection. It should be overwritten if you want to do 661 # something before/after creating a new connection. The default 662 # implementation uses `get_connection_pool` to obtain a pool and 663 # create a new connection in the newly obtained pool. 664 pass 665 666 def get_or_create_connection_pool(self, params: dict): 667 # This is a high layer on top of `get_connection_pool` for 668 # implementing a cache of created connection pools. It should be 669 # overwritten if you want change the default behavior. 670 pass 671 672 def make_connection_params(self, url: str) -> dict: 673 # The responsibility of this method is to convert basic connection 674 # parameters and other settings to fully connection pool ready 675 # connection parameters. 676 pass 677 678 def connect(self, url: str): 679 # This is really a public API and entry point for this factory 680 # class. This encapsulates the main logic of creating the 681 # previously mentioned `params` using `make_connection_params` and 682 # creating a new connection using the `get_connection` method. 683 pass 684 685Use the sentinel connection factory 686^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 687 688In order to facilitate using `Redis Sentinels`_, django-redis comes with a 689built in sentinel connection factory, which creates sentinel connection pools. 690In order to enable this functionality you should add the following: 691 692 693.. code-block:: python 694 695 # Enable the alternate connection factory. 696 DJANGO_REDIS_CONNECTION_FACTORY = 'django_redis.pool.SentinelConnectionFactory' 697 698 # These sentinels are shared between all the examples, and are passed 699 # directly to redis Sentinel. These can also be defined inline. 700 SENTINELS = [ 701 ('sentinel-1', 26379), 702 ('sentinel-2', 26379), 703 ('sentinel-3', 26379), 704 ] 705 706 CACHES = { 707 "default": { 708 "BACKEND": "django_redis.cache.RedisCache", 709 # The hostname in LOCATION is the primary (service / master) name 710 "LOCATION": "redis://service_name/db", 711 "OPTIONS": { 712 # While the default client will work, this will check you 713 # have configured things correctly, and also create a 714 # primary and replica pool for the service specified by 715 # LOCATION rather than requiring two URLs. 716 "CLIENT_CLASS": "django_redis.client.SentinelClient", 717 718 # Sentinels which are passed directly to redis Sentinel. 719 "SENTINELS": SENTINELS, 720 721 # kwargs for redis Sentinel (optional). 722 "SENTINEL_KWARGS": {}, 723 724 # You can still override the connection pool (optional). 725 "CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool", 726 }, 727 }, 728 729 # A minimal example using the SentinelClient. 730 "minimal": { 731 "BACKEND": "django_redis.cache.RedisCache", 732 733 # The SentinelClient will use this location for both the primaries 734 # and replicas. 735 "LOCATION": "redis://minimal_service_name/db", 736 737 "OPTIONS": { 738 "CLIENT_CLASS": "django_redis.client.SentinelClient", 739 "SENTINELS": SENTINELS, 740 }, 741 }, 742 743 # A minimal example using the DefaultClient. 744 "other": { 745 "BACKEND": "django_redis.cache.RedisCache", 746 "LOCATION": [ 747 # The DefaultClient is [primary, replicas...], but with the 748 # SentinelConnectionPool it only requires one "is_master=0". 749 "redis://other_service_name/db?is_master=1", 750 "redis://other_service_name/db?is_master=0", 751 ], 752 "OPTIONS": {"SENTINELS": SENTINELS}, 753 }, 754 755 # A minimal example only using only replicas in read only mode (and 756 # the DefaultClient). 757 "readonly": { 758 "BACKEND": "django_redis.cache.RedisCache", 759 "LOCATION": "redis://readonly_service_name/db?is_master=0", 760 "OPTIONS": {"SENTINELS": SENTINELS}, 761 }, 762 } 763 764.. _Redis Sentinels: https://redis.io/topics/sentinel 765 766Pluggable parsers 767~~~~~~~~~~~~~~~~~ 768 769redis-py (the Python Redis client used by django-redis) comes with a pure 770Python Redis parser that works very well for most common task, but if you want 771some performance boost, you can use hiredis. 772 773hiredis is a Redis client written in C and it has its own parser that can be 774used with django-redis. 775 776.. code-block:: python 777 778 "OPTIONS": { 779 "PARSER_CLASS": "redis.connection.HiredisParser", 780 } 781 782Pluggable clients 783~~~~~~~~~~~~~~~~~ 784 785django-redis is designed for to be very flexible and very configurable. For it, 786it exposes a pluggable backends that make easy extend the default behavior, and 787it comes with few ones out the box. 788 789Default client 790^^^^^^^^^^^^^^ 791 792Almost all about the default client is explained, with one exception: the 793default client comes with replication support. 794 795To connect to a Redis replication setup, you should change the ``LOCATION`` to 796something like: 797 798.. code-block:: python 799 800 "LOCATION": [ 801 "redis://127.0.0.1:6379/1", 802 "redis://127.0.0.1:6378/1", 803 ] 804 805The first connection string represents the primary server and the rest to 806replica servers. 807 808WARNING: Replication setup is not heavily tested in production environments. 809 810Shard client 811^^^^^^^^^^^^ 812 813This pluggable client implements client-side sharding. It inherits almost all 814functionality from the default client. To use it, change your cache settings to 815something like this: 816 817.. code-block:: python 818 819 CACHES = { 820 "default": { 821 "BACKEND": "django_redis.cache.RedisCache", 822 "LOCATION": [ 823 "redis://127.0.0.1:6379/1", 824 "redis://127.0.0.1:6379/2", 825 ], 826 "OPTIONS": { 827 "CLIENT_CLASS": "django_redis.client.ShardClient", 828 } 829 } 830 } 831 832WARNING: Shard client is still experimental, so be careful when using it in 833production environments. 834 835Herd client 836^^^^^^^^^^^ 837 838This pluggable client helps dealing with the thundering herd problem. You can read more about it 839on link: `Wikipedia <http://en.wikipedia.org/wiki/Thundering_herd_problem>`_ 840 841Like previous pluggable clients, it inherits all functionality from the default client, adding some 842additional methods for getting/setting keys. 843 844.. code-block:: python 845 846 CACHES = { 847 "default": { 848 "BACKEND": "django_redis.cache.RedisCache", 849 "LOCATION": "redis://127.0.0.1:6379/1", 850 "OPTIONS": { 851 "CLIENT_CLASS": "django_redis.client.HerdClient", 852 } 853 } 854 } 855 856This client exposes additional settings: 857 858- ``CACHE_HERD_TIMEOUT``: Set default herd timeout. (Default value: 60s) 859 860Pluggable serializer 861~~~~~~~~~~~~~~~~~~~~ 862 863The pluggable clients serialize data before sending it to the server. By 864default, django-redis serializes the data using the Python ``pickle`` module. 865This is very flexible and can handle a large range of object types. 866 867To serialize using JSON instead, the serializer ``JSONSerializer`` is also 868available. 869 870.. code-block:: python 871 872 CACHES = { 873 "default": { 874 "BACKEND": "django_redis.cache.RedisCache", 875 "LOCATION": "redis://127.0.0.1:6379/1", 876 "OPTIONS": { 877 "CLIENT_CLASS": "django_redis.client.DefaultClient", 878 "SERIALIZER": "django_redis.serializers.json.JSONSerializer", 879 } 880 } 881 } 882 883There's also support for serialization using `MsgPack`_ (that requires the 884msgpack library): 885 886.. code-block:: python 887 888 CACHES = { 889 "default": { 890 "BACKEND": "django_redis.cache.RedisCache", 891 "LOCATION": "redis://127.0.0.1:6379/1", 892 "OPTIONS": { 893 "CLIENT_CLASS": "django_redis.client.DefaultClient", 894 "SERIALIZER": "django_redis.serializers.msgpack.MSGPackSerializer", 895 } 896 } 897 } 898 899.. _MsgPack: http://msgpack.org/ 900 901Pluggable Redis client 902~~~~~~~~~~~~~~~~~~~~~~ 903 904django-redis uses the Redis client ``redis.client.StrictClient`` by default. It 905is possible to use an alternative client. 906 907You can customize the client used by setting ``REDIS_CLIENT_CLASS`` in the 908``CACHES`` setting. Optionally, you can provide arguments to this class by 909setting ``REDIS_CLIENT_KWARGS``. 910 911.. code-block:: python 912 913 CACHES = { 914 "default": { 915 "OPTIONS": { 916 "REDIS_CLIENT_CLASS": "my.module.ClientClass", 917 "REDIS_CLIENT_KWARGS": {"some_setting": True}, 918 } 919 } 920 } 921 922 923Closing Connections 924~~~~~~~~~~~~~~~~~~~ 925 926The default django-redis behavior on close() is to keep the connections to Redis server. 927 928You can change this default behaviour for all caches by the ``DJANGO_REDIS_CLOSE_CONNECTION = True`` 929in the django settings (globally) or (at cache level) by setting ``CLOSE_CONNECTION: True`` in the ``OPTIONS`` 930for each configured cache. 931 932Setting True as a value will instruct the django-redis to close all the connections (since v. 4.12.2), irrespectively of its current usage. 933 934.. code-block:: python 935 936 CACHES = { 937 "default": { 938 "BACKEND": "django_redis.cache.RedisCache", 939 "LOCATION": "redis://127.0.0.1:6379/1", 940 "OPTIONS": { 941 "CLIENT_CLASS": "django_redis.client.DefaultClient", 942 "CLOSE_CONNECTION": True, 943 } 944 } 945 } 946 947SSL/TLS and Self-Signed certificates 948~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 949 950In case you encounter a Redis server offering a TLS connection using a 951self-signed certificate you may disable certification verification with the 952following: 953 954.. code-block:: python 955 956 CACHES = { 957 "default": { 958 "BACKEND": "django_redis.cache.RedisCache", 959 "LOCATION": "rediss://127.0.0.1:6379/1", 960 "OPTIONS": { 961 "CLIENT_CLASS": "django_redis.client.DefaultClient", 962 "CONNECTION_POOL_KWARGS": {"ssl_cert_reqs": None} 963 } 964 } 965 } 966 967 968License 969------- 970 971.. code-block:: text 972 973 Copyright (c) 2011-2015 Andrey Antukh <niwi@niwi.nz> 974 Copyright (c) 2011 Sean Bleier 975 976 All rights reserved. 977 978 Redistribution and use in source and binary forms, with or without 979 modification, are permitted provided that the following conditions 980 are met: 981 1. Redistributions of source code must retain the above copyright 982 notice, this list of conditions and the following disclaimer. 983 2. Redistributions in binary form must reproduce the above copyright 984 notice, this list of conditions and the following disclaimer in the 985 documentation and/or other materials provided with the distribution. 986 3. The name of the author may not be used to endorse or promote products 987 derived from this software without specific prior written permission. 988 989 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS`` AND ANY EXPRESS OR 990 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 991 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 992 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 993 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 994 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 995 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 996 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 997 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 998 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 999 1000 1001