WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit e0c234f

Browse files
authored
Merge pull request #798 from oliverhaas/feat/sorted-set-methods-with-mixins
feat: add sorted set operations and mixins for RedisCache
2 parents 09d05e8 + 2dc6eae commit e0c234f

File tree

10 files changed

+643
-1
lines changed

10 files changed

+643
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ dump.rdb
2727
.coverage
2828
coverage.xml
2929
cobertura.xml
30+
CLAUDE.md

.ruff.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,6 @@ ban-relative-imports = "all"
178178

179179
# pickle is used on purpose and its use is discouraged
180180
"django_redis/serializers/pickle.py" = ["S301"]
181+
182+
# min/max are official Redis parameter names matching redis-py API
183+
"django_redis/client/mixins/sorted_sets.py" = ["A002"]

changelog.d/797.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add sorted set operations (zadd, zrange, zrem, etc.) and mixins for RedisCache

django_redis/cache.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,60 @@ def hkeys(self, *args, **kwargs):
278278
@omit_exception
279279
def hexists(self, *args, **kwargs):
280280
return self.client.hexists(*args, **kwargs)
281+
282+
# Sorted Set Operations
283+
@omit_exception
284+
def zadd(self, *args, **kwargs):
285+
return self.client.zadd(*args, **kwargs)
286+
287+
@omit_exception
288+
def zcard(self, *args, **kwargs):
289+
return self.client.zcard(*args, **kwargs)
290+
291+
@omit_exception
292+
def zcount(self, *args, **kwargs):
293+
return self.client.zcount(*args, **kwargs)
294+
295+
@omit_exception
296+
def zincrby(self, *args, **kwargs):
297+
return self.client.zincrby(*args, **kwargs)
298+
299+
@omit_exception
300+
def zpopmax(self, *args, **kwargs):
301+
return self.client.zpopmax(*args, **kwargs)
302+
303+
@omit_exception
304+
def zpopmin(self, *args, **kwargs):
305+
return self.client.zpopmin(*args, **kwargs)
306+
307+
@omit_exception
308+
def zrange(self, *args, **kwargs):
309+
return self.client.zrange(*args, **kwargs)
310+
311+
@omit_exception
312+
def zrangebyscore(self, *args, **kwargs):
313+
return self.client.zrangebyscore(*args, **kwargs)
314+
315+
@omit_exception
316+
def zrank(self, *args, **kwargs):
317+
return self.client.zrank(*args, **kwargs)
318+
319+
@omit_exception
320+
def zrem(self, *args, **kwargs):
321+
return self.client.zrem(*args, **kwargs)
322+
323+
@omit_exception
324+
def zremrangebyscore(self, *args, **kwargs):
325+
return self.client.zremrangebyscore(*args, **kwargs)
326+
327+
@omit_exception
328+
def zrevrange(self, *args, **kwargs):
329+
return self.client.zrevrange(*args, **kwargs)
330+
331+
@omit_exception
332+
def zrevrangebyscore(self, *args, **kwargs):
333+
return self.client.zrevrangebyscore(*args, **kwargs)
334+
335+
@omit_exception
336+
def zscore(self, *args, **kwargs):
337+
return self.client.zscore(*args, **kwargs)

django_redis/client/default.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from redis.typing import AbsExpiryT, EncodableT, ExpiryT, KeyT, PatternT
2424

2525
from django_redis import pool
26+
from django_redis.client.mixins import SortedSetMixin
2627
from django_redis.exceptions import CompressorError, ConnectionInterrupted
2728
from django_redis.util import CacheKey
2829

@@ -40,7 +41,7 @@ def glob_escape(s: str) -> str:
4041
return special_re.sub(r"[\1]", s)
4142

4243

43-
class DefaultClient:
44+
class DefaultClient(SortedSetMixin):
4445
def __init__(self, server, params: dict[str, Any], backend: BaseCache) -> None:
4546
self._backend = backend
4647
self._server = server
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from django_redis.client.mixins.protocols import ClientProtocol
2+
from django_redis.client.mixins.sorted_sets import SortedSetMixin
3+
4+
__all__ = ["ClientProtocol", "SortedSetMixin"]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from typing import Any, Optional, Protocol, Union
2+
3+
from redis import Redis
4+
from redis.typing import KeyT
5+
6+
7+
class ClientProtocol(Protocol):
8+
"""
9+
Protocol for client methods required by mixins.
10+
11+
Any class using django-redis mixins must implement these methods.
12+
"""
13+
14+
def make_key(
15+
self,
16+
key: KeyT,
17+
version: Optional[int] = None,
18+
prefix: Optional[str] = None,
19+
) -> KeyT:
20+
"""Create a cache key with optional version and prefix."""
21+
...
22+
23+
def encode(self, value: Any) -> Union[bytes, int]:
24+
"""Encode a value for storage in Redis."""
25+
...
26+
27+
def decode(self, value: Union[bytes, int]) -> Any:
28+
"""Decode a value retrieved from Redis."""
29+
...
30+
31+
def get_client(self, write: bool = False) -> Redis:
32+
"""Get a Redis client instance for read or write operations."""
33+
...

0 commit comments

Comments
 (0)