Django REST Framework,只有管理员可以删除或放置

Jac*_*aco 0 python django rest django-rest-framework

我想问如何控制 Django Rest Framework 中的对象权限,效果如下:

  • User没有能力DELETE也没有PUT
  • Admin是一个User也可以DELETE并且PUT
  • 为了访问 API /SAFE_METHODS User必须Authenticated

我尝试过标准权限,例如permissions.IsAdminUserIsAuthenticatedOrReadOnly,但没有匹配。

下面是否有一个标准的权限可以实现?如果没有,下一步最好的步骤是什么,通过 Django 模型或 DRF 控制权限?

| API end-points        | HTTP Method   | Authenticate  | Permissions  | Result                                       |
|---------------------- |-------------  |------------   |------------  |------------------------------------------    |
| /products             | GET           | User          | User         | List of product                              |
| /products             | POST          | User          | User         | Create new product                           |
| /products/{product_pk}| GET           | User          | User         | Retrieve details of particular product       |
| /products/{product_pk}| PUT           | Admin         | Admin        | Fully update particular product's info       |
| /products/{product_pk}| PATCH         | User          | User         | Partially update particular product's info   |
| /products/{product_pk}| DELETE        | Admin         | Admin        | Delete particular product's details from DB  |
Run Code Online (Sandbox Code Playgroud)

序列化器.py

class ProductSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'
Run Code Online (Sandbox Code Playgroud)

视图.py

class ProductView(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    authentication_classes = [authentication.SessionAuthentication, authentication.TokenAuthentication]
    permission_classes = (permissions.IsAdminUser,)
Run Code Online (Sandbox Code Playgroud)

urls.py

router_v1 = routers.DefaultRouter()
router_v1.register('products', ProductView)

urlpatterns = [
    path('v1/', include(router_v1.urls)),
    path('api-token-auth/', views.obtain_auth_token, name='api-token-auth'),
    path('api-auth/', include('rest_framework.urls'))
]
Run Code Online (Sandbox Code Playgroud)

JPG*_*JPG 8

将方法重写get_permissions(...)

class ProductView(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    authentication_classes = [authentication.SessionAuthentication,
                              authentication.TokenAuthentication]
    permission_classes = (permissions.IsAdminUser,)

    def get_permissions(self):
        if self.request.method in ['PUT', 'DELETE']:
            return [permissions.IsAdminUser()]
        return [permissions.IsAuthenticated()]
Run Code Online (Sandbox Code Playgroud)