У меня есть базовое приложение, в котором есть пользователи и задачи, и я хочу, чтобы TaskDetails был доступен только владельцу. Взгляды, права доступа и настройки являются следующие:Django REST Framework: разрешения на уровне объектов не работают в соответствии с учебным пособием
views.py:
from cardinal.permissions import IsOwner
class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permissions_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwner)
permissions.py:
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
print("Hit IsOWnerOrReadOnly")
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
class IsOwner(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
print("Hit IsOwner")
return obj.owner == request.user
class IsUser(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
print("Hit IsUser")
return obj.username == request.user.username
settings.py:
REST_FRAMEWORK = {
# 'DEFAULT_PERMISSION_CLASSES': (
# 'rest_framework.permissions.IsAuthenticated',
# 'rest_framework.permissions.IsAuthenticatedOrReadOnly',
# 'cardinal.permissions.IsOwnerOrReadOnly',
# 'cardinal.permissions.IsOwner',
#),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}
Когда я логин как «Боб», я могу получить доступ к задачам «Susi», и разрешения не срабатывают. Когда я отказываюсь от комментариев по умолчанию в настройках, все работает правильно, но я не хочу устанавливать каждое разрешение, которое я пишу, как «Default» для его работы.
Я посмотрел на некоторые другие ответы и один предложил переопределение метода get_object в пределах TaskDetail Вид с:
def get_object(self):
obj = get_object_or_404(self.get_queryset())
self.check_object_permissions(self.request, obj)
return obj
Когда я попробовал это, я получаю ошибку:
get() returned more than one Task -- it returned 7!
Как я сделать так, чтобы разрешения на уровне объекта использовались должным образом, не устанавливая их в настройках по умолчанию?
обновление
Не знаю, как и почему, но я получил его на работу, импортируя все приложение и указав полный путь.
import cardinal
class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
permission_classes = (cardinal.permissions.IsOwner,)
Я опробовал этот фрагмент кода, и теперь всякий раз, когда Я перехожу к TaskDetail, он возвращает «деталь»: «Не найден. Я помещаю в него какие-то заявления печати, и он попадает в предложение else, но никогда не ударяет по разрешению IsOwner для какой-либо задачи. Любая идея? –
@KyleTruong It звучит так: 'get_object_or_404' возвращает 404, это ответ по умолчанию от этой функции, когда объект не найден. – YPCrumble
Насколько я могу судить,' self.check_object_permissions (s elf.request, obj) 'метод ничего не возвращает. Следовательно, его нужно просто называть. При необходимости он будет поднимать исключение. В противном случае переходите. – onekiloparsec