django-redis使用
1. 安装
安装:
pip install django-redis
2. 配置
在 Django 项目的 settings.py 中配置缓存后端为 Redis,主要修改 CACHES 配置项。
# settings.py
CACHES = {
"default": {
# 指定缓存后端为 django_redis
"BACKEND": "django_redis.cache.RedisCache",
# Redis 连接地址(格式:redis://[:密码]@主机:端口/数据库编号)
"LOCATION": "redis://127.0.0.1:6379/1", # 数据库 1(默认 0)
"OPTIONS": {
# 指定 Redis 客户端(基于 redis-py)
"CLIENT_CLASS": "django_redis.client.DefaultClient",
# 可选:连接池配置(优化性能)
"CONNECTION_POOL_KWARGS": {
"max_connections": 100, # 最大连接数
},
# 可选:密码(如果 Redis 配置了密码)
# "PASSWORD": "your_redis_password",
}
}
}
若需用 Redis 存储 Django 会话(替代默认的数据库存储),添加以下配置:
# settings.py
# 会话存储引擎改为 Redis
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# 使用上面配置的 "default" 缓存
SESSION_CACHE_ALIAS = "default"
3. 使用
1. 获取客户端
获取原始Redis客户端
from django_redis import get_redis_connection
# 获取连接(默认使用 "default" 缓存配置)
conn = get_redis_connection("default") # "default" 对应 CACHES 中的键
2. 操作命令
1. 字符串(String)
字符串是 Redis 最基本的数据类型,可存储文本、数字等,适合缓存简单数据(如用户信息、计数器)。
常用命令示例:
| 命令 | 作用 | 示例 | 返回值(及解码) |
|---|---|---|---|
set(key, value) |
设置键值对(覆盖已有键) | conn.set("name", "zhangsan") |
True(成功) |
get(key) |
获取键对应的值 | conn.get("name") |
b'zhangsan' → 解码:conn.get("name").decode("utf-8") → 'zhangsan' |
setex(key, seconds, value) |
设置带过期时间的键值对(原子操作) | conn.setex("code", 60, "123456") # 60 秒后过期 |
True(成功) |
incr(key) |
对键的数值自增 1(键不存在则初始化为 0 后 + 1) | conn.incr("count") # 初始 count 为 0 → 自增后为 1 |
自增后的值(1) |
incrby(key, n) |
对键的数值自增 n(n 为整数) | conn.incrby("count", 5) # count 从 1 → 6 |
自增后的值(6) |
decr(key) |
对键的数值自减 1 | conn.decr("count") # count 从 6 → 5 |
自减后的值(5) |
append(key, value) |
向已有字符串末尾追加内容 | conn.append("name", "_male") # name 原为 "zhangsan" → 变为 "zhangsan_male" |
追加后字符串的长度(13) |
strlen(key) |
获取字符串长度 | conn.strlen("name") |
长度(13) |
2. 列表(List)
列表是有序的字符串集合(可重复),底层是双向链表,适合实现消息队列、最新列表等场景(如朋友圈动态、任务队列)。
常用命令示例:
| 命令 | 作用 | 示例 | 返回值(及说明) |
|---|---|---|---|
lpush(key, *values) |
向列表左侧(头部)插入一个 / 多个元素 | conn.lpush("mylist", "a", "b", "c") |
插入后列表的长度(3) |
rpush(key, *values) |
向列表右侧(尾部)插入一个 / 多个元素 | conn.rpush("mylist", "d") # 列表变为 [c, b, a, d](左侧为头,右侧为尾) |
插入后列表的长度(4) |
lpop(key) |
移除并返回列表左侧(头部)第一个元素 | conn.lpop("mylist") # 移除 "c" |
被移除的元素(b'c') |
rpop(key) |
移除并返回列表右侧(尾部)第一个元素 | conn.rpop("mylist") # 移除 "d" |
被移除的元素(b'd') |
lrange(key, start, end) |
获取列表中 [start, end] 区间的元素(start=0 表示第一个,end=-1 表示最后一个) | conn.lrange("mylist", 0, -1) # 列表当前为 [b, a] |
元素列表([b'b', b'a']) |
llen(key) |
获取列表长度 | conn.llen("mylist") |
长度(2) |
lrem(key, count, value) |
从列表中删除 count 个值为 value 的元素(count>0 从左删;count<0 从右删;count=0 删所有) | conn.lrem("mylist", 1, "b") # 从左删 1 个 "b" |
被删除的元素数量(1) |
lset(key, index, value) |
将列表指定索引的元素替换为 value(索引越界会报错) | conn.lset("mylist", 0, "x") # 列表原为 [a] → 变为 [x] |
True(成功) |
3. 哈希(Hash)
哈希适合存储对象类数据(如用户信息、商品属性),每个哈希可包含多个字段(field)和对应的值(value)。
常用命令示例:
| 命令 | 作用 | 示例 | 返回值(及说明) |
|---|---|---|---|
hset(key, field, value) |
给哈希表设置一个字段和值 | conn.hset("user:1", "name", "zhangsan") |
1(新增字段);0(字段已存在,仅更新值) |
hset(key, mapping={}) |
批量设置哈希表的字段和值(mapping 为字典) | conn.hset("user:1", mapping={"age": 20, "gender": "male"}) |
成功设置的字段数量(2) |
hget(key, field) |
获取哈希表中指定字段的值 | conn.hget("user:1", "name") |
字段值(b'zhangsan') |
hgetall(key) |
获取哈希表中所有字段和值 | conn.hgetall("user:1") |
字典形式({b'name': b'zhangsan', b'age': b'20', b'gender': b'male'}) |
hkeys(key) |
获取哈希表中所有字段名 | conn.hkeys("user:1") |
字段名列表([b'name', b'age', b'gender']) |
hvals(key) |
获取哈希表中所有字段值 | conn.hvals("user:1") |
字段值列表([b'zhangsan', b'20', b'male']) |
hexists(key, field) |
判断哈希表中是否存在指定字段 | conn.hexists("user:1", "name") |
True(存在);False(不存在) |
hdel(key, *fields) |
删除哈希表中一个 / 多个字段 | conn.hdel("user:1", "gender") |
被删除的字段数量(1) |
hincrby(key, field, amount) |
对哈希表中指定字段的数值增减(amount 为整数) | conn.hincrby("user:1", "age", 1) # age 从 20 → 21 |
增减后的值(21) |
4. 集合(Set)
集合是无序的字符串集合(元素唯一),适合存储去重数据(如标签、粉丝列表),支持交集、并集等集合运算。
常用命令示例:
| 命令 | 作用 | 示例 | 返回值(及说明) |
|---|---|---|---|
sadd(key, *members) |
向集合添加一个 / 多个元素(重复元素会被忽略) | conn.sadd("tags", "python", "django", "redis") |
成功添加的元素数量(3) |
smembers(key) |
获取集合中所有元素 | conn.smembers("tags") |
元素集合({b'python', b'django', b'redis'}) |
sismember(key, member) |
判断元素是否在集合中 | conn.sismember("tags", "python") |
True(存在);False(不存在) |
scard(key) |
获取集合中元素的数量 | conn.scard("tags") |
数量(3) |
srem(key, *members) |
从集合中删除一个 / 多个元素 | conn.srem("tags", "redis") |
被删除的元素数量(1) |
spop(key, count=1) |
随机删除并返回集合中 count 个元素 | conn.spop("tags", 1) # 随机删除 1 个元素 |
被删除的元素(如 [b'django']) |
sinter(key1, key2) |
求两个集合的交集(同时存在于两个集合的元素) | conn.sadd("tags2", "django", "flask"); conn.sinter("tags", "tags2") |
交集元素({b'django'}) |
sunion(key1, key2) |
求两个集合的并集(所有元素去重) | conn.sunion("tags", "tags2") |
并集元素({b'python', b'django', b'flask'}) |
5. 有序集合(Sorted Set)
有序集合类似集合,但每个元素关联一个 分数(score),Redis 按分数对元素排序,适合实现排行榜、带权重的任务队列等。
常用命令示例:
| 命令 | 作用 | 示例 | 返回值(及说明) |
|---|---|---|---|
zadd(key, mapping={}, nx=False) |
向有序集合添加元素(mapping 为 {元素:分数};nx=True 表示仅添加不存在的元素) | conn.zadd("ranking", {"user1": 80, "user2": 90, "user3": 70}) |
成功添加的元素数量(3) |
zrange(key, start, end, withscores=False) |
按分数升序获取 [start, end] 区间的元素(withscores=True 同时返回分数) | conn.zrange("ranking", 0, -1, withscores=True) |
元素列表([(b'user3', 70.0), (b'user1', 80.0), (b'user2', 90.0)]) |
zrevrange(key, start, end, withscores=False) |
按分数降序获取元素(与 zrange 相反) | conn.zrevrange("ranking", 0, -1) |
降序元素([b'user2', b'user1', b'user3']) |
zscore(key, member) |
获取元素的分数 | conn.zscore("ranking", "user2") |
分数(90.0) |
zincrby(key, amount, member) |
增加元素的分数(amount 可为负数) | conn.zincrby("ranking", 5, "user1") # user1 分数从 80 → 85 |
增减后的分数(85.0) |
zrank(key, member) |
获取元素按分数升序的排名(从 0 开始) | conn.zrank("ranking", "user1") # 此时 user1 分数 85,排名第 1 |
排名(1) |
zrem(key, *members) |
从有序集合中删除元素 | conn.zrem("ranking", "user3") |
被删除的元素数量(1) |
6. 通用命令
以下命令可操作任意类型的键:
| 命令 | 作用 | 示例 | 返回值(及说明) |
|---|---|---|---|
exists(key) |
判断键是否存在 | conn.exists("name") |
1(存在);0(不存在) |
delete(*keys) |
删除一个 / 多个键(无论类型) | conn.delete("name", "mylist") |
被删除的键数量(2) |
expire(key, seconds) |
给键设置过期时间(秒) | conn.expire("user:1", 3600) # 1 小时后过期 |
True(成功);False(键不存在) |
ttl(key) |
查看键的剩余过期时间(秒) | conn.ttl("user:1") |
剩余秒数(如 3500);-1(永久有效);-2(已过期) |
type(key) |
查看键的类型(string/list/hash/set/zset 等) | conn.type("user:1") |
类型(b'hash') |
keys(pattern) |
查找匹配 pattern 的所有键(生产环境慎用,可能阻塞 Redis) | conn.keys("user:*") # 匹配所有以 user: 开头的键 |
键列表([b'user:1']) |
7. 注意事项
- 字节类型解码:所有返回值默认是
bytes类型,需用decode("utf-8")转为字符串(如conn.get("name").decode("utf-8"))。 - 命令大小写:Redis 原生命令通常大写(如
SET),但redis-py中支持小写(如conn.set()),效果一致。 - 批量操作效率:对大量数据操作时,建议用 管道(Pipeline) 减少网络往返(见下方示例)。
- 生产环境慎用
keys():keys(*)会遍历所有键,数据量大时会阻塞 Redis,建议用scan()替代。
4. 高级设置
1. 设置全局过期时间
CACHES = {
"default": {
# ... 其他配置 ...
"TIMEOUT": 300, # 全局默认 5 分钟过期(None 表示永久)
}
}
2. 批量删除键
from django_redis import get_redis_connection
conn = get_redis_connection("default")
# 删除所有以 "user:" 开头的键
conn.delete_pattern("user:*")
4. 管道操作
批量执行命令,减少网络返(提升性能)
conn = get_redis_connection("default")
pipe = conn.pipeline() # 创建管道
# 批量添加命令
pipe.set("a", 1).set("b", 2).incr("a")
# 执行所有命令
pipe.execute() # 返回 [True, True, 2]
发表评论