Использование аннулирования кэша для пользовательского разрешения django
В настоящее время я работаю над кэшем для пользовательских разрешений в Django.
Структура для предоставления пользователям/организациям доступа к определенным областям приложения выглядит следующим образом:

Имеется в виду, что пользователь может иметь доступ к функции либо через свою организацию, либо как сам пользователь. Мне нужен кэш с ключами-значениями, который хранит все функции, к которым пользователь/организация имеет доступ в виде строки. Таким образом, когда пользователь запрашивает доступ к определенному представлению, класс разрешения сначала извлекает все функции для этого пользователя из кэша. Я реализовал это следующим образом:
class UserPermissionCache:
def __init__(self):
self.redis = StrictRedis(
host=settings.REDIS_RATE_LIMITING_URL,
port=settings.REDIS_RATE_LIMITING_PORT,
db=settings.REDIS_RATE_LIMITING_DB,
)
self.validation = datetime.now().strftime("%m%d%Y%H%M%S")
def status_key(self, member):
return f"user:features:{self.validation}:{member.uuid}"
def set_user_features(self, user, key):
features = Feature.objects.filter(
Q(enabled_for_all=True)
| Q(enabled_for_users=user)
| Q(enabled_for_organizations=user.only_organization)
)
result = FEATURE_STRING_SEPERATOR.join(
feature.code for feature in features
)
if not self.redis.set(key, result, settings.USER_FEATURES_TIMEOUT):
logging.warning(f"Couldn't set features for user: {user.uuid}")
return result
def get_user_features(self, member):
key = self.status_key(member)
try:
result = self.redis.get(key)
except ConnectionError:
logger.error(
"ConnectionError, Failed to fetch feature permission for user",
extra={"member": member.uuid},
)
return None
if result is None:
result = self.set_user_features(member, key)
result = result.split(FEATURE_STRING_SEPERATOR)
else:
result = result.decode("utf-8").split(FEATURE_STRING_SEPERATOR)
return result
def reset_user_features(self, sender, **kwargs):
for member in organization_members:
key = self.status_key(member)
self.redis.delete(key)
def update_validation_key(self, sender, instance, **kwargs):
self.validation = datetime.now().strftime("%m%d%Y%H%M%S")
user_permission_cache = UserPermissionCache()
m2m_changed.connect(user_permission_cache.reset_user_features, sender=Feature.enabled_for_organizations.through)
post_save.connect(user_permission_cache.update_validation_key, sender=Feature)
Моя проблема заключается в проверке кэша. Я установил таймаут для записи в кэше на 15 минут. Всякий раз, когда я хочу добавить функции организациям или изменить функцию как администратор, я хочу, чтобы кэш также обновлялся, чтобы каждый пользователь получал немедленный доступ. Я попытался решить эту проблему, добавив время к ключу. Всякий раз, когда функция обновляется, я изменяю и ключ, что означает, что кэш больше не может найти старую пару ключ-значение и просто создает новую запись с обновленной функцией. Я просто не знаю, что делать, когда представление вызывается для добавления характеристик в организацию. Для этого я использую сигнал m2m_changed Signal. Я надеялся, что есть лучшее решение, чем это.