我注意到在多个线程中,我们需要使用更好的缓存,例如“Redis”,而不是 Django 的默认“LocMemCache”,尤其是在生产中。
我有多个设置文件,包括
base.py
和 master.py
我已在
base.py
中添加了我的 Redis 缓存,如以下代码片段所示:
CACHES = {
"alternate": {
"BACKEND": "redis_cache.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"DB": 1,
"CLIENT_CLASS": "redis_cache.client.DefaultClient",
}
}
}
我故意将其交替使用,因为我不想更改应用程序中的缓存。
不在我的自定义油门中,我有以下实现:
from rest_framework.throttling import UserRateThrottle
from myproject.settings.base import CACHES
class CustomThrottle(UserRateThrottle):
scope = 'custom_throttle'
cache = CACHES['alternate']
节流率存在于同一个
base.py
文件中
但是,当我向该端点运行请求时,遇到以下错误。
line 26, in throttle_success
self.cache.set(self.key, self.history, self.duration)
AttributeError: 'dict' object has no attribute 'set'
我知道在这种情况下我必须覆盖throttle_success,但我不确定到底要改变什么。 帮助?! 谢谢。
您的配置有问题,您的设置也应该有默认缓存。
CACHES = {
"alternate": {
"BACKEND": "redis_cache.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"DB": 1,
"CLIENT_CLASS": "redis_cache.client.DefaultClient",
}
},
"default": {
"BACKEND": "redis_cache.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"DB": 2,
"CLIENT_CLASS": "redis_cache.client.DefaultClient",
}
}
}
一旦定义了这样的设置,您应该使用缓存对象而不是 CACHE 设置来更新 CustomThrottle。
from django.core.cache import caches
class CustomThrottle(UserRateThrottle):
scope = 'custom_throttle'
cache = caches['alternate']
我正在尝试实现一个解决方案,其中 Django 的
LocMemCache
用作默认缓存,Redis 作为备用缓存来处理速率限制会话。但是,当我尝试在 throttles.py
中打印缓存对象时,我注意到所有缓存条目都存储在默认缓存 (LocMemCache
) 中,并且没有任何条目存储在备用缓存 (Redis
) 中。
这导致速率限制功能无法按预期运行,因为未使用备用缓存 (Redis)。
设置.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
},
"alternate": {
"BACKEND": "django_redis.cache.RedisCache",
'LOCATION': 'redis://127.0.0.1:6379',
"OPTIONS": {
"DB": 1,
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
节流阀.py
class GetProductThrottle(UserRateThrottle):
scope = 'list_products'
cache = caches['alternate']
def get_cache_key(self, request, view):
# Create a session for anonymous users
if not request.session.session_key:
request.session.create() # This forces the session to be created
return f'throttle_{self.scope}_{request.session.session_key}'
def allow_request(self, request, view):
if request.method == 'GET':
cache_key = self.get_cache_key(request, view)
num_requests = self.cache.get(cache_key, 0)
print(f"Current number of requests: {num_requests}")
return super().allow_request(request, view)
return True
def wait(self):
return super().wait()