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)),
]
تقديم طلب GET إلى / api / mymodel / 123 / custom /
يجب استدعاء has_object_permission () باستخدام MyModel.objects.get(pk=123)
كعنصر.
طلب المسار المخصص في شكل / api / mymodel / 123 / custom / سوف يستدعي has_permission () في MyPermissions ، لكن ليس has_object_permission () على الرغم من أنه مسار تفصيلي.
نحتاج إلى توثيق حقيقة أنك ستحصل على has_object_permission
فقط إذا اتصلت بـ get_object
.
هذا يبدو غير بديهي. تُستخدم الاستدعاءات مثل / api / object / 123 / method / بشكل عام لاستدعاء طريقة ما على مثيل الكائن مع المعرف 123 ويبدو أن التحقق من إذن الكائن سيكون سلوكًا متوقعًا. وإلا في كل مرة يقوم فيها شخص ما بعمل مسارات تفصيلية مخصصة ، فسيتعين عليه استرداد الكائن والتحقق يدويًا من الأذونات والمتابعة. عند هذه النقطة ، فإن استدعاء 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, so ignore """
return True
أعتقد أنني فهمت ذلك الآن. إذا قمت باستدعاء get_object () في مساراتي المخصصة ، فسيتم استدعاء has_object_permission (). لا يزال يبدو غير بديهي ، ولكن على الأقل هناك حل واضح.
يسعدني النظر في طلب سحب ملموس للتوثيق ، ولكن كما هو الحال أعتقد أن ما لدينا هو حول الملاءمة في http://www.django-rest-framework.org/api-guide/permissions/ #object -level- أذونات
إغلاق هذا ، ولكن كما لوحظ أنه يمكن النظر في إعادة الصياغة / الإضافات المحددة.
التعليق الأكثر فائدة
نحتاج إلى توثيق حقيقة أنك ستحصل على
has_object_permission
فقط إذا اتصلت بـget_object
.