Как найти user_id в конечной точке Django
У меня есть эта конечная точка Django:
def get(http_request: HttpRequest, id: str):
book_account_id = UUID(id)
user_id: UUID = http_request.user.id
affiliated_price_subscriptions = None
response = BookAccountService.filter(
id=book_account_id
).prefetch_related(
Prefetch(
'subscription_set',
queryset=SubscriptionRepository.filter(
active=True
).prefetch_related(
Prefetch(
'pricesubscription_set',
queryset=PriceSubscriptionRepository.filter(
Q(status=PriceSubscription.PriceSubscriptionStatus.PENDING) |
Q(status=PriceSubscription.PriceSubscriptionStatus.REQUIRES_PAYMENT)
),
to_attr='price_subscriptions'
)
),
to_attr='subscriptions'
)
).first()
affiliated_price_subscriptions = list(chain.from_iterable(
subscription.price_subscriptions for subscription in response.subscriptions
))
# The user must be part of the group that owns the book account
# or the book acc must have at least one pending subscription
if not PersonGroupService.exists(
person__user_id=user_id,
group__bookaccount__id=book_account_id
) and affiliated_price_subscriptions is None:
return RestResponse(
status=status.HTTP_200_OK,
data=Response(
code=24,
error=True,
messages=[
f"User with ID {user_id} does not have access to book account with ID {book_account_id}."
],
data=None,
).to_dict(),
)
return (...)
В основном, это делается для того, чтобы получить book_account
либо если:
- user.id принадлежит человеку, который входит в группу этого book_account.
- У книжного счета есть связанная с ним прайс-подписка со статусом
PENDING
илиPENDING_PAYMENT
.
Я удалил is_authenticated=True
, поскольку для 2) вам не нужно входить в систему, чтобы получить данные book_account. Однако, когда я вызываю конечную точку при аутентификации, я получаю ошибку, поскольку user_id равен null. Я понял, что единственный способ не делать его null - это установить is_authenticated=True, но если я так сделаю, то не смогу выполнить 2). Есть ли способ сделать и то, и другое? Или я должен создать разные конечные точки для обоих случаев?
Используйте http_request.user.is_authenticated
, чтобы проверить, вошел ли пользователь в систему. Если да, то вы можете получить доступ к http_request.user.id. Если нет, просто пропустите проверки, требующие аутентификации пользователя.
Я добавил в ваш код две вещи, которые должны помочь
1. попытка-исключение для проверки UUID 2. Проверяется http_request.user.is_authenticated 3. Альтернативный запасной вариант для неаутентифицированных пользователей 4. Ответ «Доступ запрещен», если аутентифицированный доступ к группе или действительная цена подписки не выполняется
from django.http import JsonResponse
from django.db.models import Q, Prefetch
from itertools import chain
from uuid import UUID
def get(http_request: HttpRequest, id: str):
try:
book_account_id = UUID(id)
except ValueError:
return JsonResponse({
"code": 400,
"error": True,
"messages": ["Invalid book account ID."],
"data": None,
}, status=400)
affiliated_price_subscriptions = None
response = BookAccountService.filter(
id=book_account_id
).prefetch_related(
Prefetch(
'subscription_set',
queryset=SubscriptionRepository.filter(
active=True
).prefetch_related(
Prefetch(
'pricesubscription_set',
queryset=PriceSubscriptionRepository.filter(
Q(status=PriceSubscription.PriceSubscriptionStatus.PENDING) |
Q(status=PriceSubscription.PriceSubscriptionStatus.REQUIRES_PAYMENT)
),
to_attr='price_subscriptions'
)
),
to_attr='subscriptions'
)
).first()
if response:
affiliated_price_subscriptions = list(chain.from_iterable(
subscription.price_subscriptions for subscription in response.subscriptions
))
if http_request.user.is_authenticated:
user_id = http_request.user.id
# Check if the user is part of the group that owns the book account
if PersonGroupService.exists(
person__user_id=user_id,
group__bookaccount__id=book_account_id
):
return JsonResponse({
"code": 200,
"error": False,
"messages": ["Access granted."],
"data": response,
}, status=200)
# If not authenticated, or if the user isn't part of the group,
# check if there are affiliated price subscriptions
if affiliated_price_subscriptions:
return JsonResponse({
"code": 200,
"error": False,
"messages": ["Access granted based on price subscriptions."],
"data": response,
}, status=200)
return JsonResponse({
"code": 403,
"error": True,
"messages": ["Access denied."],
"data": None,
}, status=403)