【发布时间】:2020-10-07 17:30:28
【问题描述】:
大家好,我想在我的类 UserDetail 中使用 APIView 的自定义权限,但我注意到此权限没有执行,我的权限称为“IsOwner”,因为我想允许用户根据用户身份。每次我提出请求时都会出错:
{
"detail": "Not found."
}
views.py
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import status, permissions, generics, viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import MyTokenObtainPairSerializer, UserSerializer, GroupSerializer
from .models import User
from authentication.permisssions import CustomObjectPermissions, IsOwner
from django.contrib.auth.models import Group
from django.http import Http404
class ObtainTokenPairView(TokenObtainPairView):
permission_classes = [permissions.AllowAny,]
serializer_class = MyTokenObtainPairSerializer
class UserList(APIView):
"""
List all snippets, or create a new snippet.
"""
permission_classes = [CustomObjectPermissions]
serializer_class = UserSerializer
def get_queryset(self):
users = User.objects.all().order_by('-date_joined')
return users
def get(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = UserSerializer(self.get_queryset(), context=serializer_context, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = UserSerializer(data=request.data, context=serializer_context)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
permission_classes = [CustomObjectPermissions|IsOwner]
serializer_class = UserSerializer
def get_queryset(self):
pk = self.kwargs["pk"]
return User.objects.filter(id = pk)
def get_object(self, pk):
try:
print(pk)
user = User.objects.get(pk=pk)
self.check_object_permissions(self.request, user)
return user
except User.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
user = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = UserSerializer(user, context=serializer_context)
return Response(serializer.data)
def put(self, request, pk, format=None):
user = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = UserSerializer(user,context=serializer_context, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
user = self.get_object(pk)
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class GroupList(APIView):
"""
List all snippets, or create a new snippet.
"""
permission_classes = [CustomObjectPermissions]
queryset = Group.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
def get(self, request, format=None):
groups = Group.objects.all()
serializer_context = {
'request': request,
}
serializer = GroupSerializer(groups, context=serializer_context, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = GroupSerializer(data=request.data, context=serializer_context)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class GroupDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
permission_classes = [CustomObjectPermissions]
queryset = Group.objects.all().order_by('-date_joined')
serializer_class = GroupSerializer
def get_object(self, pk):
try:
return Group.objects.get(pk=pk)
except Group.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
group = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = GroupSerializer(group, context=serializer_context)
return Response(serializer.data)
def put(self, request, pk, format=None):
group = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = GroupSerializer(group,context=serializer_context, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
group = self.get_object(pk)
group.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
permissions.py
from rest_framework.permissions import DjangoObjectPermissions, BasePermission
class CustomObjectPermissions(DjangoObjectPermissions):
"""
Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
"""
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
class IsOwner(BasePermission):
message = 'You must be the owner of this object'
def has_object_permission(self, request, view, obj):
return obj.id == request.user.id
views.py (self.check_object_permissions(self.request, user) 这行不行)
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import status, permissions, generics, viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import MyTokenObtainPairSerializer, UserSerializer, GroupSerializer
from .models import User
from authentication.permisssions import CustomObjectPermissions, IsOwner
from django.contrib.auth.models import Group
from django.http import Http404
class ObtainTokenPairView(TokenObtainPairView):
permission_classes = [permissions.AllowAny,]
serializer_class = MyTokenObtainPairSerializer
class UserList(APIView):
"""
List all snippets, or create a new snippet.
"""
permission_classes = [CustomObjectPermissions]
serializer_class = UserSerializer
def get_queryset(self):
users = User.objects.all().order_by('-date_joined')
return users
def get(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = UserSerializer(self.get_queryset(), context=serializer_context, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = UserSerializer(data=request.data, context=serializer_context)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
permission_classes = [CustomObjectPermissions|IsOwner]
serializer_class = UserSerializer
def get_queryset(self):
pk = self.kwargs["pk"]
return User.objects.filter(id = pk)
def get_object(self, pk):
try:
print(pk)
user = User.objects.get(pk=pk)
self.check_object_permissions(self.request, user)
return user
except User.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
user = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = UserSerializer(user, context=serializer_context)
return Response(serializer.data)
def put(self, request, pk, format=None):
user = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = UserSerializer(user,context=serializer_context, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
user = self.get_object(pk)
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class GroupList(APIView):
"""
List all snippets, or create a new snippet.
"""
permission_classes = [CustomObjectPermissions]
queryset = Group.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
def get(self, request, format=None):
groups = Group.objects.all()
serializer_context = {
'request': request,
}
serializer = GroupSerializer(groups, context=serializer_context, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer_context = {
'request': request,
}
serializer = GroupSerializer(data=request.data, context=serializer_context)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class GroupDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
permission_classes = [CustomObjectPermissions]
queryset = Group.objects.all().order_by('-date_joined')
serializer_class = GroupSerializer
def get_object(self, pk):
try:
return Group.objects.get(pk=pk)
except Group.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
group = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = GroupSerializer(group, context=serializer_context)
return Response(serializer.data)
def put(self, request, pk, format=None):
group = self.get_object(pk)
serializer_context = {
'request': request,
}
serializer = GroupSerializer(group,context=serializer_context, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
group = self.get_object(pk)
group.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
【问题讨论】:
-
如果你删除 IsOwner,它可以工作吗?
-
你确定存在
User这样的pk吗?响应{"detail": "Not found."}表示在UserDetail.get_object()中引发了 404。 -
@Vincent 如果我删除 self.check_object_permissions(self.request, user) 正在工作
-
@wiaterb pk 是正确的,因为如果我评论此行现在正在工作 self.check_object_permissions(self.request, user)
-
permission_classes 应该是元组,例如:permission_classes = (CustomObjectPermissions, isOwner)
标签: python python-3.x django api django-rest-framework