ネストされた構造を持つ API を実装しています。
動物園だとしましょう。ケージ ID 1 を取得するためGET /api/cage/
にケージのリストを取得するために呼び出すことができますが、そのケージ内の動物のリストを取得することもできます。GET /api/cage/1/
GET /api/cage/1/animals/
私が抱えている問題は、許可に関するものです。ケージ自体が見える場合にのみ、ケージ内の動物を見ることができるはずです。関連する許可クラスにhas_object_permission()
戻ると、ケージ自体を見ることができるはずです。True
何らかの理由で、has_object_permission()
GET を実行すると呼び出されます/api/cage/1/
がhas_permission()
、 を呼び出すと呼び出されますGET /api/cage/1/animals/
。またhas_permission()
、権限を確認するためのオブジェクトへのアクセス権がありません。何か不足していますか?どうすればいいですか?
私のケージビューセットは多かれ少なかれこのように見えます
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)
これは DRF のバグのようです。詳細なルートは、正しい許可チェックを呼び出しません。この問題を DRF 開発者に報告しようとしましたが、報告が消えたようです。次に何をすべきかわからない。アイデア?
DRF で投稿した問題が戻ってきて、応答がありました。チェックのみのようで、意図した動作ではhas_permission()
ありません。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