Django-rest-framework: Izin objek tidak diperiksa pada rute tampilan khusus

Dibuat pada 23 Mei 2016  ·  4Komentar  ·  Sumber: encode/django-rest-framework

Langkah-langkah untuk mereproduksi

class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MySerializer
    authentication_classes = (MyAuth, )
    permission_classes = (MyPermissions, )

    @detail_route(methods=["GET", ])
    def custom(self, request, pk=None):
        return Response('whatever')

from rest_framework import routers
router = routers.SimpleRouter() 
router.register('mymodel', MyViewSet)
urlpatterns = [
    url(r'^api/', include(router.urls)),
]

buat permintaan GET ke /api/mymodel/123/custom/

Perilaku yang diharapkan

has_object_permission() harus dipanggil dengan MyModel.objects.get(pk=123) sebagai objek.

Perilaku sebenarnya

request ke custom route dalam bentuk /api/mymodel/123/custom/ akan memanggil has_permission() di MyPermissions, tetapi tidak has_object_permission() meskipun itu adalah rute detail.

Documentation

Komentar yang paling membantu

Kami perlu mendokumentasikan fakta bahwa Anda hanya akan mendapatkan has_object_permission dipanggil hanya jika Anda memanggil get_object .

Semua 4 komentar

Kami perlu mendokumentasikan fakta bahwa Anda hanya akan mendapatkan has_object_permission dipanggil hanya jika Anda memanggil get_object .

Ini tampaknya kontra-intuitif. Panggilan seperti /api/object/123/method/ umumnya digunakan untuk memanggil beberapa metode pada instance objek dengan ID 123 dan tampaknya memeriksa izin objek akan menjadi perilaku yang diharapkan. Jika tidak, setiap kali seseorang membuat rute detail khusus, mereka harus mengambil objek, memeriksa izin secara manual, dan melanjutkan. Pada saat itu, memanggil has_object_permission() tetap tidak masuk akal. Jadi dalam setiap skenario di mana izin tingkat objek digunakan, beberapa boilerplate seperti ini harus digunakan

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, so ignore """
        return True

Saya pikir saya mengerti sekarang. Jika saya memanggil get_object() di rute kustom saya, has_object_permission() akan dipanggil. Tampaknya masih kontra-intuitif, tetapi setidaknya ada solusi yang jelas.

Saya akan dengan senang hati mempertimbangkan permintaan tarik konkret untuk dokumentasi, tetapi sebagaimana adanya, saya pikir apa yang kami dapatkan cukup memadai di http://www.Django-rest-framework.org/api-guide/permissions/ #objek -level -izin

Menutup ini, tetapi seperti yang dicatat, pengulangan/penambahan spesifik _dapat_ dipertimbangkan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat