DjangoRestFramework - 当使用`get_queryset()`

时间:2015-11-10 01:52:43

标签: django django-rest-framework

这是我的观点:

class PostListByUsername(generics.ListAPIView):
    serializer_class = SpillSerializer
    permission_classes = (IsAuthenticated, IsLikeOrOwnerDeleteOrReadOnly,)

    def get_queryset(self):
        username = self.kwargs['username']
        user = User.objects.get(username=username)
        if user.userextended.location != self.request.user.userextended.location:
            content = {'Post': ['You cannot view the posts of a user who is not from your location.']}
            return Response(content, status=status.HTTP_403_FORBIDDEN)

        return Post.objects.filter(owner__username=username)

问题是,当我输入if语句并尝试返回响应时,Django提出错误说:

ContentNotRenderedError at /post/username
The response content must be rendered before it can be iterated over.

请注意,/post/username是调用PostListByUsername的内容。话虽如此,在get_queryset()方法内部进行验证并返回带有错误消息的状态代码的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您无法从Sub Test() With CurrentDb.OpenRecordset("SELECT * FROM Table1", dbOpenForwardOnly) IsThisAGoodPractice() End With End Sub 返回Response对象来处理错误 - 它必须返回一个查询集(令人惊讶)。

但是,你可以提出一个get_queryset,它将被包装在适当的响应中。您可以查看APIException及其子类here

虽然您可以在APIException中执行不同的检查,但我认为在您的情况下将其放在其他位置更合适 - 例如添加您自己的权限类(您不必在哪里根本不提出任何例外情况:

get_queryset

或以class IsFromSameLocation(permissions.BasePermission): message = 'You cannot view the posts of a user who is not from your location.' def has_permission(self, request, view): username = view.kwargs['username'] user = User.objects.get(username=username) return user.userextended.location == \ request.user.userextended.location #... class PostListByUsername(generics.ListAPIView): serializer_class = SpillSerializer permission_classes = (IsAuthenticated, IsLikeOrOwnerDeleteOrReadOnly,\ IsFromSameLocation,) #... list方式执行此操作。

添加自定义权限是一种更简洁的方式,因为它可以重复使用,因此您可以将其添加到其他视图中。

一般来说,常识暗示您必须完全按照retrieve中的说法进行操作,如果不能,则提出相应的例外情况。