首页 > 解决方案 > Django:自定义权限无效并在视图内检查返回错误

问题描述

我有一个CreateAPIView带有自定义权限类的通用视图 ( ),TransactionCreatorIsSenderOrAdmin但它对视图根本没有影响,即使权限类只包含return False. 我认为文档中说明了这样做的原因:

另请注意,通用视图只会检查检索单个模型实例的视图的对象级权限。如果您需要对列表视图进行对象级过滤,则需要单独过滤查询集。有关更多详细信息,请参阅过滤文档。

由于我要检索多个模型实例,因此我的方法是在视图本身的 perform_create 中进行检查,但我得到一个错误,我不知道为什么,因为它在没有权限检查的情况下工作。这是错误:

Exception Type: AttributeError
Exception Value: 'collections.OrderedDict' object has no attribute 'date'
Exception Location: .../transactions/api/serializers.py in get_date, line 17

这是我的看法:

class TransactionCreateAPIView(generics.CreateAPIView):
    queryset = Transaction.objects.all()
    serializer_class = TransactionSerializer
    permission_classes = [IsAuthenticated, TransactionCreatorIsSenderOrAdmin]

    def perform_create(self, serializer):
        amount = self.request.data['amount']
        message = self.request.data['message']
        from_account_iban = self.request.data['from_account']
        from_account_obj = BankAccount.objects.get(iban=from_account_iban)
        to_account_iban = self.request.data['to_account']
        to_account_obj = BankAccount.objects.get(iban=to_account_iban)        
        if from_account_obj.user == self.request.user or self.request.user.is_staff == True:
            serializer.save(amount=Decimal(amount), 
                        from_account=from_account_obj, 
                        to_account=to_account_obj,
                        message=message)
        else:
            return Response(serializer.errors, status=403)

这是序列化程序:

class TransactionSerializer(serializers.ModelSerializer):
    date = serializers.SerializerMethodField(read_only=True)
    from_account = serializers.SerializerMethodField()
    to_account = serializers.SerializerMethodField()
    slug = serializers.SlugField(read_only=True)

    class Meta:
        model = Transaction
        fields = '__all__'

    def get_date(self, instance):
        return instance.date.strftime("%B %d %Y")

    def get_from_account(self, instance):
        return instance.from_account.iban

    def get_to_account(self, instance):
        return instance.to_account.iban

标签: pythondjangopermissions

解决方案


解决方案不是使用以下 else 语句:

return Response(serializer.errors, status=403)

使用这个:

raise PermissionDenied(detail=None, code=status.HTTP_403_FORBIDDEN)

推荐阅读