Оптимизация N+1 запросов к ролям пользователей через select_related в middleware
This commit is contained in:
@@ -33,6 +33,24 @@ class TenantAdminAccessMiddleware:
|
||||
}, status=403)
|
||||
|
||||
def __call__(self, request):
|
||||
# Оптимизация: загружаем роль пользователя один раз для всего запроса
|
||||
if hasattr(request, 'user') and request.user.is_authenticated:
|
||||
schema_name = getattr(connection, 'schema_name', 'public')
|
||||
# Только для tenant схем и CustomUser загружаем роль с select_related
|
||||
if schema_name != 'public':
|
||||
from accounts.models import CustomUser
|
||||
if isinstance(request.user, CustomUser):
|
||||
# Проверяем, не загружена ли уже роль
|
||||
if not hasattr(request.user, '_role_prefetched'):
|
||||
try:
|
||||
# Загружаем пользователя с ролью через select_related
|
||||
request.user = CustomUser.objects.select_related(
|
||||
'tenant_role__role'
|
||||
).get(pk=request.user.pk)
|
||||
request.user._role_prefetched = True
|
||||
except CustomUser.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Проверяем, это admin URL?
|
||||
if request.path.startswith('/admin/'):
|
||||
# Импортируем здесь чтобы избежать circular imports
|
||||
|
||||
@@ -110,8 +110,22 @@ class RoleService:
|
||||
|
||||
@staticmethod
|
||||
def get_user_role(user):
|
||||
"""Получить роль пользователя в текущем тенанте"""
|
||||
"""
|
||||
Получить роль пользователя в текущем тенанте.
|
||||
Оптимизация: использует уже загруженные данные если есть select_related.
|
||||
"""
|
||||
try:
|
||||
# Проверяем, есть ли уже загруженная роль через select_related
|
||||
if hasattr(user, 'tenant_role'):
|
||||
# Проверяем, что tenant_role загружен (а не RelatedObjectDoesNotExist)
|
||||
try:
|
||||
user_role = user.tenant_role
|
||||
if user_role.is_active and hasattr(user_role, 'role'):
|
||||
return user_role.role
|
||||
except UserRole.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Если нет prefetch - делаем запрос
|
||||
user_role = UserRole.objects.get(user=user, is_active=True)
|
||||
return user_role.role
|
||||
except UserRole.DoesNotExist:
|
||||
|
||||
Reference in New Issue
Block a user