簡體   English   中英

如何在 ViewSet DRF 中對 perform_create 應用權限

[英]How to apply permissions on perform_create in ViewSet DRF

這是我的視圖集:

class MyViewSet(ModelViewSet):
    serializer_class = MySerializer
    queryset = MyClass.objects.all()

   def get_serializer_class(self):
        if self.request.user.is_superuser:
            return self.serializer_class 

        return serializers.MyUserSerializer   

    def perform_create(self, serializer):
        employee = models.Employee.objects.get(user=self.request.user)
        serializer.save(employee=employee)

我想在 perform_create 之前申請權限,這個 perform_create() 應該只在當前登錄的用戶不是超級用戶時調用。 如果當前登錄的用戶是超級用戶,則應調用默認的 perform_create function。

編輯:基本上我想實現以下邏輯,但要借助權限。

def perform_create(self, serializer):
        if self.request.user.is_superuser:
            serializer.save()
        else:
            employee = models.Employee.objects.get(user=self.request.user)
            serializer.save(employee=employee)

怎么做?

試試這個邏輯

def perform_create(self, serializer):
  self.request.data.get("title", None)  # read data from request
  if self.request.user.is_authenticated and not self.request.user.is_superuser:
      instance = serializer.save(author=self.request.user)
  else:
      instance = serializer.save() 

您可以在 Viewset class 中使用 permission_classes

from rest_framework.permissions import IsAuthenticated
class MyViewSet(ModelViewSet):
    permission_classes = (IsAuthenticated,)
    serializer_class = MySerializer
    queryset = MyClass.objects.all()

    ...

試試這樣:

class MyViewSet(ModelViewSet):
    serializer_class = MySerializer
    queryset = MyClass.objects.all()

    def get_serializer_class(self):
        if self.request.user.is_superuser:
            return self.serializer_class 

        return serializers.MyUserSerializer   

    def perform_create(self, serializer):
        employee = models.Employee.objects.get(user=self.request.user)
        serializer.save(employee=employee)

    def has_permission(self, request, view):
        if request.user.is_superuser:
            return True
        return super().has_permission(request, view)

只有當用戶不是超級用戶並且有權限時, perform_create方法才會被調用。 has_permission方法將為超級用戶返回True

您可以像這樣編寫自定義權限class:

class CustomPermission(permissions.BasePermission):

    def has_permission(self, request, view):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True
        # write permission is allowed only for superusers
        return request.user.is_superuser

然后在您的視圖中使用此權限:

class MyViewSet(ModelViewSet):
    permission_classes = (IsAuthenticated, CustomPermission,)
    serializer_class = MySerializer

不幸的是,您想要使用 Permission 實現的邏輯是不可能的,因為perform_create確實執行object level permission ,因此邏輯需要像您在問題中提到的那樣在 perform_create 方法中。

您可以創建自定義權限,請參閱以下示例。

from rest_framework import permissions

class IsNotSuperuserPermission(permissions.BasePermission):
    message = 'You are super user.' # Your custom message.

    def has_permission(self, request, view):
        if request.user.is_authenticated:
            return not request.user.is_superuser
        self.message = 'you are not logged in' # your custom message
        return False



class MyViewSet(ModelViewSet):
    serializer_class = MySerializer
    queryset = MyClass.objects.all()

    def get_serializer_class(self):
        if self.request.user.is_superuser:
            return self.serializer_class 

        return serializers.MyUserSerializer 

    def get_permissions(self):
        if self.action == 'create':
            permission_classes = [IsNotSuperuserPermission]
        else:
            permission_classes = [IsAuthenticated]
        return [permission() for permission in permission_classes]

    def perform_create(self, serializer):
        employee = models.Employee.objects.get(user=self.request.user)
        serializer.save(employee=employee)

get_permissions中,您可以為每個操作分配一個或多個權限。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM