Repository: joke2k/django-environ
Pull request #122 (2017-05-04 07:58:17)

Feature: support for multiple redis locations
Fix for #121 

Allows configuring redis master/slave or shards. Includes tests & readme.


Patch:
diff --git a/.gitignore b/.gitignore
index dc9606a..34f75db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,7 @@ nosetests.xml
 .pydevproject
 .idea
 .projectile
-.ropeproject
\ No newline at end of file
+.ropeproject
+
+# pyenv/pyenv-virtualenv
+.python-version
\ No newline at end of file
diff --git a/README.rst b/README.rst
index 314d095..a8e5598 100644
--- a/README.rst
+++ b/README.rst
@@ -227,6 +227,15 @@ In order to use unsafe characters you have to encode with ``urllib.parse.encode`
 
 See https://perishablepress.com/stop-using-unsafe-characters-in-urls/ for reference.
 
+Multiple redis cache locations
+------------------------------
+
+For redis cache, `multiple master/slave or shard locations <http://niwinz.github.io/django-redis/latest/#_pluggable_clients>`_ can be configured as follows:
+
+.. code-block::
+
+    CACHE_URL='rediscache://master:6379,slave1:6379,slave2:6379/1'
+
 Email settings
 --------------
 
@@ -267,6 +276,11 @@ Django-environ is licensed under the MIT License - see the `LICENSE_FILE`_ file
 Changelog
 =========
 
+`pending`
+---------
+
+  - Support for django-redis multiple locations (master/slave, shards)
+
 `0.4.2 - 13-April-2017 <https://github.com/joke2k/django-environ/compare/v0.4.1...v0.4.2>`__
 --------------------------------------------------------------------------------------------
 
diff --git a/environ/environ.py b/environ/environ.py
index 24368b3..949253d 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -452,8 +452,8 @@ class Env(object):
                 scheme = url.scheme.replace('cache', '')
             else:
                 scheme = 'unix'
-
-            config['LOCATION'] = scheme + '://' + url.netloc + url.path
+            locations = [scheme + '://' + loc + url.path for loc in url.netloc.split(',')]
+            config['LOCATION'] = locations[0] if len(locations) == 1 else locations
 
         if url.query:
             config_options = {}


Test patch:
diff --git a/environ/test.py b/environ/test.py
index b7f79ba..4cd48c5 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -471,6 +471,17 @@ class CacheTestSuite(unittest.TestCase):
         self.assertEqual(REDIS_DRIVER, url['BACKEND'])
         self.assertEqual(url['LOCATION'], 'redis://:redispass@127.0.0.1:6379/0')
 
+    def test_redis_multi_location_parsing(self):
+        url = 'rediscache://host1:6379,host2:6379,host3:9999/1'
+        url = Env.cache_url_config(url)
+
+        self.assertEqual(url['BACKEND'], REDIS_DRIVER)
+        self.assertEqual(url['LOCATION'], [
+            'redis://host1:6379/1',
+            'redis://host2:6379/1',
+            'redis://host3:9999/1',
+        ])
+
     def test_redis_socket_url(self):
         url = 'redis://:redispass@/path/to/socket.sock?db=0'
         url = Env.cache_url_config(url)
@@ -479,7 +490,7 @@ class CacheTestSuite(unittest.TestCase):
         self.assertEqual(url['OPTIONS'], {
             'DB': 0
         })
-
+    
     def test_options_parsing(self):
         url = 'filecache:///var/tmp/django_cache?timeout=60&max_entries=1000&cull_frequency=0'
         url = Env.cache_url_config(url)