Как найти 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 либо если:

  1. user.id принадлежит человеку, который входит в группу этого book_account.
  2. У книжного счета есть связанная с ним прайс-подписка со статусом 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)
Вернуться на верх