#django #serialization #django-rest-framework #permissions
Вопрос:
Я пытаюсь создать REST API с помощью django-rest-фреймворка. Мой вопрос в том, могу ли я распечатать экземпляр has_object_permission
метода, чтобы я мог видеть, что происходит в этой части. Я пытаюсь сделать так, чтобы только владелец объекта мог обновлять и удалять объект, но прямо сейчас любой может удалить или обновить любой объект. Пожалуйста, скажите, есть ли другой способ сделать это, кроме разрешений. Можем ли мы сделать все это с помощью проверок в сериализаторе. Если да, то, пожалуйста, объясните мне это тоже на примере. Я буду очень благодарен.
class ObjectOwnerPermission(BasePermission): message = "This object is expired." # custom error message def has_object_permission(self, request, view, obj): if request.user.is_authenticated: return True return False if obj.author == request.user: return True return False class RetrieveUpdateProjectAPIView(generics.RetrieveUpdateAPIView,ObjectOwnerPermission): """This endpoint allows for updating a specific Project by passing in the id of the Project to update/Retrieve""" permissions_classes = [ObjectOwnerPermission] queryset = Project.objects.all() serializer_class = serializers.ProjectSerializer class DeleteProjectAPIView(generics.DestroyAPIView,ObjectOwnerPermission): """This endpoint allows for deletion of a specific Project from the database""" permissions_classes = [ObjectOwnerPermission] queryset = Project.objects.all() serializer_class = serializers.ProjectSerializer
Ответ №1:
Ваши разрешения не работают, потому что вы возвращаетесь True
в свой ObjectOwnerPermission
, когда пользователь прошел проверку подлинности, что означает, что ЛЮБОЙ, кто прошел проверку подлинности, может передать это разрешение.
ИЗМЕНИТЬ: В исходном вопросе permissionS_classes
, который использовался вместо permission_classes
Вот моя исправленная версия:
class ObjectOwnerPermission(BasePermission): message = "This object is expired." # custom error message def has_object_permission(self, request, view, obj): return obj.author == request.user class RetrieveUpdateProjectAPIView(generics.RetrieveUpdateAPIView): """This endpoint allows for updating a specific Project by passing in the id of the Project to update/Retrieve""" permission_classes = [IsAuthenticated, ObjectOwnerPermission] queryset = Project.objects.all() serializer_class = serializers.ProjectSerializer class DeleteProjectAPIView(generics.DestroyAPIView): """This endpoint allows for deletion of a specific Project from the database""" permission_classes = [IsAuthenticated, ObjectOwnerPermission] queryset = Project.objects.all() serializer_class = serializers.ProjectSerializer
- НЕ наследуйте класс разрешений в своих представлениях — он должен использоваться только в
permission_classes
- если вы хотите связать свое разрешение в цепочку, оно должно быть реализовано в
permission_classes
списке - классы разрешений считываются слева направо, что означает, что
IsAuthenticated
это проверяется первым перед вашим классом (в вашем классе вы уверены, что пользователь вошел в систему).
Комментарии:
1. Прежде всего, большое вам спасибо за ваше время и ответ, и я обновил код в своем проекте, но все равно любой пользователь может обновить или удалить любой объект. проверка разрешений, я думаю, не работает
2. О, используется плохое слово … оно должно быть
permission_classes
«нетpermissionS_classes
«. Я обновил свой ответ.3. Идеальный брат!. Все прошло гладко. Я действительно ценю это.
4. Брат, что делать, если кто-нибудь может получить объект, но только владелец может обновить объект. Прямо сейчас только владелец может увидеть свой проект и обновить его.
5.Вы можете зарегистрироваться
action.name
has_object_permission
и использовать текущий оператор дляdestroy
update
, аpartial_update
действия в противном случае возвращают значение True, например.if view.action in ('destroy', 'update', 'partial_update'): return obj.author == request.user