Вернуть Http-ответ в get_queryset - PullRequest
0 голосов
/ 02 ноября 2018

Я использую get_queryset, в ListAPIView

Я хочу проверить токен доступа пользователя, прежде чем предоставить список, я сделал следующее, но проблема в том, что набор get_query не возвращает ответ, есть ли способ вернуть ответ, или я должен использовать альтернативу:

это мой класс в views.py:

class ListProductsOfCategory(generics.ListAPIView):
    serializer_class = ProductSerializer
    lookup_url_kwarg = 'category_id'

    def get_queryset(self):
        # I get the token here from the headers 
        token = self.request.META.get("HTTP_TOKEN", "")
        if not token:
            return Response(
                data={
                    "message": "no token!"
                },
                status=status.HTTP_400_BAD_REQUEST
            )
        if not UserAccess.objects.filter(accessToken=token).exists():
            return Response(
                data={
                    "message": "invalid token!"
                },    
                status=status.HTTP_400_BAD_REQUEST
            )
        category_id = self.kwargs.get(self.lookup_url_kwarg)
        return Product.objects.filter(category_id=category_id)

обратите внимание, что все работает отлично, если я удалил часть, связанную с токеном.

спасибо заранее.

после последнего обновления это ответ:

enter image description here

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Я не на 100%, если я правильно понял, но я считаю, что вы можете просто использовать обычные механизмы аутентификации, которые обеспечивает DRF. В этом конкретном примере, я думаю, этот раздел документации по DRF должен показать вам, как это сделать «DRF»: Настройка схемы аутентификации

Если вы добавите схему TokenAuthentication в свое приложение, вам не нужно проверять токен в вашем методе get_queryset, но вы можете просто использовать декораторы для ограничения доступа для представлений на основе функций или permission_classes для представлений на основе классов:

Посмотреть на основе

Я думаю, это то, что вас больше всего заинтересует.

class ListProductsOfCategory(generics.ListAPIView):
    serializer_class = ProductSerializer
    lookup_url_kwarg = 'category_id'

    authentication_classes = (TokenAuthentication, ) # Add others if desired
    permission_classes = (IsAuthenticated,)

Маршрут на основе

Если вы хотите ограничить доступ только для некоторых ваших маршрутов (например, только для сообщений или подробных представлений), вы можете написать свой собственный класс разрешений. Например, см. Этот вопрос здесь: Как добавить разрешения django rest framework только для определенного метода?

0 голосов
/ 02 ноября 2018

Я бы посоветовал вам переместить логику проверки токенов в метод dispatch(). Это лучшее место, чем get_queryset. Или даже лучше написать свой собственный класс аутентификации, чтобы разделить его между представлениями.

С некоторыми исправлениями (см. Обновленный get_queryset ()) это может быть:

UPDATE

Я думаю, вы можете пойти со встроенным restframework.exceptions.AuthenticationFailed. Если вас не устраивают исключения DRF по умолчанию , вы можете создать свои собственные исключения. Например где-то в exceptions.py:

from rest_framework.exceptions import APIException

class MissingTokenException(APIException):
    status_code = 400
    default_detail = 'Your request does not contain token'
    default_code = 'no_token'

class InvalidTokenException(APIException):
    status_code = 400
    default_detail = 'Your request contain invalid token'
    default_code = 'invalid_token'

Тогда вы можете использовать их в views.py:

from rest_framework import serializers
from .exceptions import MissingTokenException, InvalidTokenException

class ListProductsOfCategory(generics.ListAPIView):
    serializer_class = ProductSerializer
    lookup_url_kwarg = 'category_id'

    def dispatch(self, *args, **kwargs):
        token = self.request.META.get("HTTP_TOKEN", "")
        if not token:
            raise MissingTokenException
        if not UserAccess.objects.filter(accessToken=token).exists():
            raise InvalidTokenException
        return super().dispatch(*args, **kwargs)

    def get_queryset(self):
        qs = super().get_queryset()
        category_id = self.kwargs.get(self.lookup_url_kwarg)
        return qs.filter(category_id=category_id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...