Django REST Framework, только администратор может УДАЛИТЬ или ПОМЕСТИТЬ

#python #django #rest #django-rest-framework

#python #django #rest #django-rest-framework

Вопрос:

Я хотел бы спросить, как я могу управлять разрешениями объектов в рамках Django Rest Framework, чтобы:

  • User не имеет возможности ни DELETE PUT
  • Admin User это также может DELETE и PUT
  • Для доступа к API / SAFE_METHODS User должен быть Authenticated

Я пробовал стандартные разрешения, такие как permissions.IsAdminUser и IsAuthenticatedOrReadOnly , но не совпадают.

Есть ли стандартное разрешение для достижения ниже? Если нет, то каков наилучший следующий шаг для управления разрешениями через модели 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  |
  

Serializers.py

 class ProductSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'
  

views.py

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

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'))
]
  

Ответ №1:

Переопределите 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()]