Mhm*_*izk 1 python django django-rest-framework
我在 ListAPIView 中使用 get_queryset
我想检查用户的访问令牌,在提供列表之前,我完成了以下操作,但问题是 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)
Run Code Online (Sandbox Code Playgroud)
请注意,如果我删除了与令牌相关的部分,则一切正常。
提前致谢。
上次更新后,这是回复:
我建议您将检查令牌逻辑移动到dispatch()方法中。这是一个比 更好的地方get_queryset。或者甚至更好地编写您自己的身份验证类以便在视图之间共享它。
通过一些修复(请参阅更新的 get_queryset()),它可以是:
更新
我认为你可以使用内置的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'
Run Code Online (Sandbox Code Playgroud)
然后你可以在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)
Run Code Online (Sandbox Code Playgroud)