В чем разница между разрешением объекта и разрешением в DRF:Permission?

я путаю с BasePermission в Django-rest-framework.

здесь я определил класс: IsAuthenticatedAndOwner.

class IsAuthenticatedAndOwner(BasePermission):
    message = 'You must be the owner of this object.'
    def has_permission(self, request, view):
        print('called')
        return False
    def has_object_permission(self, request, view, obj):
        # return obj.user == request.user
        return False

используя в views.py

class StudentUpdateAPIView(RetrieveUpdateAPIView):
    serializer_class = StudentCreateUpdateSerializer
    queryset = Student.objects.all()
    lookup_field = 'pk'
    permissions_classes = [IsAuthenticatedAndOwner]

но это не работает вообще.Каждый может передать разрешение и обновить данные. The called не было напечатано.


и я использовал для определения этого класса:IsNotAuthenticated

class IsNotAuthenticated(BasePermission):
    message = 'You are already logged in.'
    def has_permission(self, request, view):
        return not request.user.is_authenticated()

он хорошо работает в функции

class UserCreateAPIView(CreateAPIView):
    serializer_class = UserCreateSerializer
    queryset = User.objects.all()
    permission_classes = [IsNotAuthenticated]

Итак, в чем разница между приведенными выше примерами и функцией has_object_permission&has_permission?

2 ответов


в принципе, первый код отрицает все, потому что has_permission вернуть False.

has_permission это проверка перед вызовом has_object_permission. Это означает, что вы нужно разрешен has_permission прежде чем вы получите любой шанс проверить тест владения.

ты хочешь:

class IsAuthenticatedAndOwner(BasePermission):
    message = 'You must be the owner of this object.'
    def has_permission(self, request, view):
        return request.user and request.user.is_authenticated
    def has_object_permission(self, request, view, obj):
        return obj.user == request.user

Это также позволит авторизованным пользователям создавать новые элементы или их список.


у нас есть следующие два метода разрешений для класса BasePermission:

  • def has_permission (self, запрос, просмотр)
  • def has_object_permission (self, request, view, obj)

эти два различных метода призвал к ограничению несанкционированных пользователей для ввода данных и манипуляции.

has_permission вызывается по всем HTTP-запросам, тогда как has_object_permission вызывается из Метод Django DRF def get_object(self). Следовательно,has_object_permission метод доступен GET, PUT, DELETE, не POST запрос.

в итоге:

  • permission_classes закольцованы над определенным списком.
  • has_object_permission метод вызывается после has_permission метод возвращает значение True за исключением метода POST (в методе POST has_permission быть только казнен).
  • , когда False значение возвращается из permission_classes метод, запрос не получает разрешения и не будет цикл больше, в противном случае, он проверяет все разрешения на цикл.
  • has_permission метод будет вызываться на всех (GET, POST, PUT, DELETE) HTTP запрос.
  • способ has_object_permission не назовут HTTP POST запрос, поэтому нам нужно ограничить его от has_permission метод.