我尝试创建一个自定义的权限类,以确保用户经过身份验证,并且尝试访问端点的经过身份验证的用户正在访问与他而不是其他用户相关的信息。 这是定制课程:
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
函数而不是 has_object_permission
类中的 IsAuthenticatedAndSameUser
函数。
我希望它使用 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}'
我尝试在视图集中自定义
get_permissions
函数,但它也不起作用。
也许这个答案会对您有帮助?
您没有分享您的方法orders的代码。您应该在其中使用 self.get_object() 来调用 has_object_permission()。