Repository: joke2k/django-environ

Issue:
0.10.0 regression - cache client_class no longer supported.  
Prior to 0.10.0 this CACHE_URL would function as expected. `redis://redis:6379/0?client_class=django_redis.client.DefaultClient`. This uses the django_redis package over the built-in Django redis support. This is desirable for a number of reasons, one being using more advanced redis commands with the Django cache abstraction.

With 0.10.0, it now generates an error. I would expect the client_class param to be supported regardless of what default exists in django-environ. Tested in Django 4.1.

```
----> 1 cache.set("foo", "bar")

File /usr/local/lib/python3.10/site-packages/django/core/cache/backends/redis.py:191, in RedisCache.set(self, key, value, timeout, version)
    189 def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
    190     key = self.make_and_validate_key(key, version=version)
--> 191     self._cache.set(key, value, self.get_backend_timeout(timeout))

File /usr/local/lib/python3.10/site-packages/django/core/cache/backends/redis.py:108, in RedisCacheClient.set(self, key, value, timeout)
    106     client.delete(key)
    107 else:
--> 108     client.set(key, value, ex=timeout)

File /usr/local/lib/python3.10/site-packages/redis/commands/core.py:2302, in BasicKeyCommands.set(self, name, value, ex, px, nx, xx, keepttl, get, exat, pxat)
   2299     pieces.append("GET")
   2300     options["get"] = True
-> 2302 return self.execute_command("SET", *pieces, **options)

File /usr/local/lib/python3.10/site-packages/redis/client.py:1255, in Redis.execute_command(self, *args, **options)
   1253 pool = self.connection_pool
   1254 command_name = args[0]
-> 1255 conn = self.connection or pool.get_connection(command_name, **options)
   1257 try:
   1258     return conn.retry.call_with_retry(
   1259         lambda: self._send_command_parse_response(
   1260             conn, command_name, *args, **options
   1261         ),
   1262         lambda error: self._disconnect_raise(conn, error),
   1263     )

File /usr/local/lib/python3.10/site-packages/redis/connection.py:1476, in ConnectionPool.get_connection(self, command_name, *keys, **options)
   1474         connection = self._available_connections.pop()
   1475     except IndexError:
-> 1476         connection = self.make_connection()
   1477     self._in_use_connections.add(connection)
   1479 try:
   1480     # ensure this connection is connected to Redis

File /usr/local/lib/python3.10/site-packages/redis/connection.py:1516, in ConnectionPool.make_connection(self)
   1514     raise ConnectionError("Too many connections")
   1515 self._created_connections += 1
-> 1516 return self.connection_class(**self.connection_kwargs)

TypeError: Connection.__init__() got an unexpected keyword argument 'CLIENT_CLASS'

In [3]: settings.CACHES
Out[3]: 
{'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache',
  'LOCATION': 'redis://redis:6379/0',
  'OPTIONS': {'CLIENT_CLASS': 'django_redis.client.DefaultClient'}}}
```
Default Django Redis in 0.10.0
Hi, 
In 0.10.0 the core Redis driver implemented in Django 4 `'django.core.cache.backends.redis.RedisCache'` has been made the default Redis driver.
This causes a regression django-redis users, the core driver is less extensive than django-redis and as such I think it should be prioritized if it is installed. This library has no reason to be here if not to be used as the main django driver so that would make more sense imo.

I can make a quick PR to fix this if you agree.

Discussion:
github-actions[bot]: Your PR was set to target `main`, PRs should be target `develop`
The base branch of this PR has been automatically changed to `develop`, please check that there are no merge conflicts.
coveralls: 
[![Coverage Status](https://coveralls.io/builds/57749825/badge)](https://coveralls.io/builds/57749825)

Coverage: 91.271% (+0.02%) from 91.255% when pulling **9e750c1f9438e8ecb1ec65a07b9767185461ff74 on legau:redis-driver** into **bec18530b41745f4ecf1f0a39d690c1e3c41d4a4 on joke2k:develop**.


Patch:
diff --git a/environ/compat.py b/environ/compat.py
index 0cec1e5..b4ffee4 100644
--- a/environ/compat.py
+++ b/environ/compat.py
@@ -10,7 +10,6 @@
 
 from pkgutil import find_loader
 
-
 if find_loader('simplejson'):
     import simplejson as json
 else:
@@ -28,14 +27,17 @@ else:
 
 def choose_rediscache_driver():
     """Backward compatibility for RedisCache driver."""
+
+    # django-redis library takes precedence
+    if find_loader('django_redis'):
+        return 'django_redis.cache.RedisCache'
+
     # use built-in support if Django 4+
     if DJANGO_VERSION is not None and DJANGO_VERSION >= (4, 0):
         return 'django.core.cache.backends.redis.RedisCache'
 
     # back compatibility with redis_cache package
-    if find_loader('redis_cache'):
-        return 'redis_cache.RedisCache'
-    return 'django_redis.cache.RedisCache'
+    return 'redis_cache.RedisCache'
 
 
 def choose_postgres_driver():


Test patch:
diff --git a/tests/test_cache.py b/tests/test_cache.py
index a762c1b..37d7b6e 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -117,21 +117,22 @@ def test_pymemcache_compat(django_version, pymemcache_installed):
 
 
 @pytest.mark.parametrize('django_version', ((4, 0), (3, 2), None))
-@pytest.mark.parametrize('redis_cache_installed', (True, False))
-def test_rediscache_compat(django_version, redis_cache_installed):
+@pytest.mark.parametrize('django_redis_installed', (True, False))
+def test_rediscache_compat(django_version, django_redis_installed):
     django_new = 'django.core.cache.backends.redis.RedisCache'
     redis_cache = 'redis_cache.RedisCache'
-    django_old = 'django_redis.cache.RedisCache'
+    django_redis = 'django_redis.cache.RedisCache'
 
     with mock.patch.object(environ.compat, 'DJANGO_VERSION', django_version):
         with mock.patch('environ.compat.find_loader') as mock_find_loader:
-            mock_find_loader.return_value = redis_cache_installed
+            mock_find_loader.return_value = django_redis_installed
             driver = environ.compat.choose_rediscache_driver()
-            if django_version and django_version >= (4, 0):
+            if django_redis_installed:
+                assert driver == django_redis
+            elif django_version and django_version >= (4, 0):
                 assert driver == django_new
             else:
-                assert driver == redis_cache if redis_cache_installed else django_old
-
+                assert driver == redis_cache
 
 def test_redis_parsing():
     url = ('rediscache://127.0.0.1:6379/1?client_class='