我尝试创建一个自定义的权限类,确保用户经过身份验证,并且尝试访问端点的经过身份验证的用户正在访问与他相关的信息,而不是其他用户。这是自定义类:
from rest_framework.permissions import BasePermission
class IsAuthenticatedAndSameUser(BasePermission):
def has_object_permission(self, request, view, obj):
if request.method == "GET" or request.method == 'DELETE':
print(request.user)
if request.user.is_authenticated and (request.user == obj.user):
return True
else:
return False
字符串
我在权限类中为Viewset提供了新的自定义类。
class AccountViewset(viewsets.ModelViewSet):
queryset = Account.objects.all()
serializer_class = AccountSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticatedAndSameUser,)
@action(detail=True, methods=['get'], permission_classes=(IsAuthenticatedAndSameUser, ))
def orders(self, request, pk, *args, **kwargs):
型
当我尝试直接访问与帐户模型相关的端点时,权限类工作正常,如:http://127.0.0.1:8000/api/accounts/2/但是它在动作装饰器上并不像预期的那样工作。当我使用与动作装饰器相关的端点时:http://127.0.0.1:8000/api/accounts/2/orders/。该类使用has_permission
函数,而不是IsAuthenticatedAndSameUser
类中的has_object_permission
函数。我希望它使用has_object_permission
函数。
使用的型号:
账户模型
class Account(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
balance = models.DecimalField(decimal_places=2, max_digits=9)
def __str__(self):
return f'Name: {self.user.username} / Balance: {self.balance}'
型
订单型号:
class Order(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
account = models.ForeignKey(Account, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
def __str__(self):
return f'AccountOf: {self.account.user.username} / ProductName: {self.product.name}'
型
我试着在viewset中自定义get_permissions
函数,但它也不起作用。
1条答案
按热度按时间fkvaft9z1#
this answer可能会帮助你?
您没有共享方法 orders 的代码。你应该在里面使用 self.get_object() 来调用 has_object_permission()。