Как установить разные access_classes для запросов GET и POST, использующих один и тот же URL? - PullRequest
2 голосов
/ 06 апреля 2019

Я строю конечные точки, используя DRF (Django Rest Framework).

django==2.1.5
djangorestframework==3.9.1
django-rest-auth
djangorestframework-jwt

У меня есть модель "Item", и я хочу установить разные access_classes для запросов GET и POST.

Вот как я это делаю:

@csrf_exempt
@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([AllowAny])
def item_list(request):
    if request.method == 'GET':
        items = Item.objects.all()
        serializer = ItemSerializer(items, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = ItemSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)

Я хочу использовать одну конечную точку для всех методов, например:

urlpatterns = [
    path('api/item/', views.item_list),
    path('api/item/<int:pk>/', views.item_details),
]

Я хочу AllowAny пользователя для GET метода запроса и проверьте, если isAdminUser для POST метод запроса

Могу ли я сделать это как во Flask, то есть один декоратор для одного метода?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2019

Поскольку вы используете Функциональные представления , невозможно переопределить какие-либо методы.Теперь вы можете создать новый класс разрешений и включить в него свою логику

# permissions.py
from rest_framework.permissions import IsAdminUser


class MyCustomPermission(IsAdminUser):
    def has_permission(self, request, view):
        if request.method == 'GET':
            return True
        else:
            return super().has_permission(request, view)

и использовать его в своем представлении как

# views.py
@csrf_exempt
@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
<b>@permission_classes([MyCustomPermission]) # chage is here </b>
def item_list(request):
    if request.method == 'GET':
        items = Item.objects.all()
        serializer = ItemSerializer(items, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = ItemSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)


Если вы планируете перейти на Представления на основе классов , вы можете сделать это, переопределив метод get_permissions().

You простой пример можно найти здесь

def get_permissions(self):
    """
    Instantiates and returns the list of permissions that this view requires.
    """
    if self.request.method == 'GET':
        permission_classes = [AllowAny]
    else:
        permission_classes = [IsAdminUser]
    return [permission() for permission in permission_classes]
1 голос
/ 06 апреля 2019

Использование на основе классов просмотр, определение и использование пользовательских разрешений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...