入れ子構造のAPIを実装しています。それは動物園だと私はGET /api/cage/
ケージIDの1を得るGET /api/cage/1/
ケージのリストを取得することができますが、私はGET /api/cage/1/animals/
ケージの動物のリストを取得することができます。私が持っている問題はパーミッションです。私はケージ自体を見ることができればケージ内の動物を見ることができます。 has_object_permission()が関連するパーミッションクラスでTrueを返すと、私はケージ自体を見ることができます。何らかの理由で、私がGET/api/cage/1 /を実行したときにhas_object_permission()が呼び出されますが、GET /api/cage/1/animals/
を呼び出したときにhas_permission()が呼び出されます。また、has_permission()を使用して、アクセス権をチェックするオブジェクトにアクセスすることはできません。何か不足していますか?これはどうすればいいですか?多かれ少なかれ、このDRFビューセットの権限チェックが正しく機能していません
class CageViewSet(ModelViewSet): queryset = Cage.objects.all() serializer_class = CageSerializer permission_classes = [GeneralZooPermissions, ] authentication_classes = [ZooTicketCheck, ] def get_queryset(self): ... code to only list cages you have permission to see ... @detail_route(methods=['GET']) def animals(self, request, pk=None): return Request(AnimalSerializer(Animal.objects.filter(cage_id=pk), many=True).data)
のように見えるビューセット
マイケージ私GeneralZooPermissionsクラスは、この(現時点では)
class GeneralZooPermissions(BasePermission): def has_permission(self, request, view): return True def has_object_permission(self, request, view, obj): return request.user.has_perm('view_cage', obj)
更新#1のようになります。これはバグであるように思えますDRF。詳細ルートは、正しい権限チェックを呼び出さない。私はこの問題をDRF開発者に報告しようとしましたが、私の報告書は消えたようです。次に何をすべきかわからない。アイデア?
更新#2:DRFで投稿した問題が戻ってきて、私は応答を得ました。 has_permission()だけをチェックし、has_object_permission()はチェックしないように見えます。私を助けないので、私はまだ解決策を探しています。この時点では、このようなものは、DRFコードの束を読み、DRFチームで問題を投稿した後に、あなたのビューがGET_OBJECTを呼び出す場合has_object_permissionは()のみ呼び出されると思われるので、
class CustomPermission(BasePermission): def has_permission(self, request, view): """we need to do all permission checking here, since has_object_permission() is not guaranteed to be called""" if 'pk' in view.kwargs and view.kwargs['pk']: obj = view.get_queryset()[0] # check object permissions here else: # check model permissions here def has_object_permission(self, request, view, obj): """ nothing to do here, we already checked everything """ return True