代码之家  ›  专栏  ›  技术社区  ›  vale383

如何在Django端点中查找user_id

  •  0
  • vale383  · 技术社区  · 5 月前

    我有一个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属于属于该bookaccount组的人。
    2. 该图书账户与相关价格订阅有关联 PENDING PENDING_PAYMENT 状态。

    我删除了 is_authenticated=True 因为对于2),您不需要登录即可获取bookaccount数据。然而,当我在经过身份验证的情况下调用端点时,由于user_id为null,我收到了一个错误。我意识到,让它不为null的唯一方法是让is_authenticated=True,但如果我这样做,我就不能做2)。有没有一种方法可以同时做到这两件事?或者,我应该为这两种情况创建不同的端点吗?

    1 回复  |  直到 5 月前
        1
  •  0
  •   Idris Olokunola    5 月前

    使用 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)