Skip to content

Commit 57386d6

Browse files
oliverhaas2ykwang
andcommitted
refactor: fix hash method parameter naming and key handling
Changed hash method parameters to align with Redis/Valkey terminology: - Renamed 'name' → 'key' (the Redis key for the hash) - Renamed 'key' → 'field' (the field within the hash) - Changed type from 'str' to 'KeyT' for consistency with other methods - Added 'version' parameter support to hlen() and hkeys() Fixed make_key() application: - make_key() now only applied to hash key (first parameter) - Fields are no longer transformed with make_key() - This fixes the namespacing issue where fields were incorrectly prefixed - hkeys() now returns plain field names without reverse_key processing Added comprehensive test for version support across all hash methods. This improves API clarity and consistency with Redis/Valkey documentation where 'key' refers to the Redis key (name of the hash structure) and 'field' refers to a field within that hash. Changed methods: - hset(key, field, value, ...) - hdel(key, field, ...) - hlen(key, ...) - hkeys(key, ...) - hexists(key, field, ...) All hash-related tests pass with the new implementation. Co-authored-by: 2ykwang <yk2ykwang@gmail.com>
1 parent 755dfb2 commit 57386d6

3 files changed

Lines changed: 55 additions & 15 deletions

File tree

changelog.d/812.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix hash method parameters: rename 'name' → 'key', 'key' → 'field' to align with Redis/Valkey terminology. Add version parameter to hlen() and hkeys(). Fix make_key() to only apply to hash key, not fields.

django_redis/client/default.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,76 +1131,80 @@ def touch(
11311131

11321132
def hset(
11331133
self,
1134-
name: str,
11351134
key: KeyT,
1135+
field: KeyT,
11361136
value: EncodableT,
11371137
version: Optional[int] = None,
11381138
client: Optional[Redis] = None,
11391139
) -> int:
11401140
"""
1141-
Set the value of hash name at key to value.
1141+
Set the value of hash key at field to value.
11421142
Returns the number of fields added to the hash.
11431143
"""
11441144
if client is None:
11451145
client = self.get_client(write=True)
11461146
nkey = self.make_key(key, version=version)
11471147
nvalue = self.encode(value)
1148-
return int(client.hset(name, nkey, nvalue))
1148+
return int(client.hset(nkey, field, nvalue))
11491149

11501150
def hdel(
11511151
self,
1152-
name: str,
11531152
key: KeyT,
1153+
field: KeyT,
11541154
version: Optional[int] = None,
11551155
client: Optional[Redis] = None,
11561156
) -> int:
11571157
"""
1158-
Remove keys from hash name.
1158+
Remove fields from hash key.
11591159
Returns the number of fields deleted from the hash.
11601160
"""
11611161
if client is None:
11621162
client = self.get_client(write=True)
11631163
nkey = self.make_key(key, version=version)
1164-
return int(client.hdel(name, nkey))
1164+
return int(client.hdel(nkey, field))
11651165

11661166
def hlen(
11671167
self,
1168-
name: str,
1168+
key: KeyT,
1169+
version: Optional[int] = None,
11691170
client: Optional[Redis] = None,
11701171
) -> int:
11711172
"""
1172-
Return the number of items in hash name.
1173+
Return the number of items in hash key.
11731174
"""
11741175
if client is None:
11751176
client = self.get_client(write=False)
1176-
return int(client.hlen(name))
1177+
nkey = self.make_key(key, version=version)
1178+
return int(client.hlen(nkey))
11771179

11781180
def hkeys(
11791181
self,
1180-
name: str,
1182+
key: KeyT,
1183+
version: Optional[int] = None,
11811184
client: Optional[Redis] = None,
11821185
) -> list[Any]:
11831186
"""
1184-
Return a list of keys in hash name.
1187+
Return a list of fields in hash key.
11851188
"""
11861189
if client is None:
11871190
client = self.get_client(write=False)
1191+
nkey = self.make_key(key, version=version)
11881192
try:
1189-
return [self.reverse_key(k.decode()) for k in client.hkeys(name)]
1193+
return [k.decode() for k in client.hkeys(nkey)]
11901194
except _main_exceptions as e:
11911195
raise ConnectionInterrupted(connection=client) from e
11921196

11931197
def hexists(
11941198
self,
1195-
name: str,
11961199
key: KeyT,
1200+
field: KeyT,
11971201
version: Optional[int] = None,
11981202
client: Optional[Redis] = None,
11991203
) -> bool:
12001204
"""
1201-
Return True if key exists in hash name, else False.
1205+
Return True if field exists in hash key, else False.
12021206
"""
12031207
if client is None:
12041208
client = self.get_client(write=False)
12051209
nkey = self.make_key(key, version=version)
1206-
return bool(client.hexists(name, nkey))
1210+
return bool(client.hexists(nkey, field))

tests/test_backend.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,41 @@ def test_hexists(self, cache: RedisCache):
871871
assert cache.hexists("foo_hash5", "foo1")
872872
assert not cache.hexists("foo_hash5", "foo")
873873

874+
def test_hash_version_support(self, cache: RedisCache):
875+
"""Test that version parameter works correctly for hash methods."""
876+
if isinstance(cache.client, ShardClient):
877+
pytest.skip("ShardClient doesn't support get_client")
878+
879+
# Set values with different versions
880+
cache.hset("my_hash", "field1", "value1", version=1)
881+
cache.hset("my_hash", "field2", "value2", version=1)
882+
cache.hset("my_hash", "field1", "different_value", version=2)
883+
884+
# Verify both versions exist independently
885+
assert cache.hexists("my_hash", "field1", version=1)
886+
assert cache.hexists("my_hash", "field2", version=1)
887+
assert cache.hexists("my_hash", "field1", version=2)
888+
assert not cache.hexists("my_hash", "field2", version=2)
889+
890+
# Verify hlen works with versions
891+
assert cache.hlen("my_hash", version=1) == 2
892+
assert cache.hlen("my_hash", version=2) == 1
893+
894+
# Verify hkeys works with versions
895+
keys_v1 = cache.hkeys("my_hash", version=1)
896+
assert len(keys_v1) == 2
897+
assert "field1" in keys_v1
898+
assert "field2" in keys_v1
899+
900+
keys_v2 = cache.hkeys("my_hash", version=2)
901+
assert len(keys_v2) == 1
902+
assert "field1" in keys_v2
903+
904+
# Verify hdel works with versions
905+
cache.hdel("my_hash", "field1", version=1)
906+
assert not cache.hexists("my_hash", "field1", version=1)
907+
assert cache.hexists("my_hash", "field1", version=2) # v2 should still exist
908+
874909
def test_sadd(self, cache: RedisCache):
875910
assert cache.sadd("foo", "bar") == 1
876911
assert cache.smembers("foo") == {"bar"}

0 commit comments

Comments
 (0)