How to add django rest framework permissions on specific method only ?
Asked Answered
M

2

15

I have following functions in rest API for User model. I want to set AllowAny permission on only POST request. Can someone help me out.

class UserList(APIView):
    """Get and post users data."""

    def get(self, request, format=None):
        """Get users."""
        users = User.objects.all()
        serialized_users = UserSerializer(users, many=True)
        return Response(serialized_users.data)

    def post(self, request, format=None):
        """Post users."""
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
Moniliform answered 5/6, 2016 at 12:57 Comment(2)
what will happen in case of GET requests?Secretarial
@RahulGupta In case of GET request Authentication is required.Moniliform
S
35

You can write a custom Permission class IsPostOrIsAuthenticated which will allow unrestricted access to POST requests but will allow only authenticated GET requests.

To implement the custom permission IsPostOrIsAuthenticated, override the BasePermission class and implement .has_permission(self, request, view) method. The method should return True if the request should be granted access, and False otherwise.

from rest_framework import permissions

class IsPostOrIsAuthenticated(permissions.BasePermission):        

    def has_permission(self, request, view):
        # allow all POST requests
        if request.method == 'POST':
            return True

        # Otherwise, only allow authenticated requests
        # Post Django 1.10, 'is_authenticated' is a read-only attribute
        return request.user and request.user.is_authenticated

So, all POST requests will be granted unrestricted access. For other requests, authentication will be required.

Now, you need to include this custom permission class in your global settings.

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'my_app.permissions.IsPostOrIsAuthenticated',
    )
}
Secretarial answered 6/6, 2016 at 4:12 Comment(4)
Might need to remove parenthesis from is_authenticated.Walkthrough
@BradenHolt Yes, post Django 1.10, its an attribute. Updated the ans. Thanks!Secretarial
what about the case where you only want to allow a specific action called via POST, but disallow all other actions performed by POST ?Hodometer
@Hodometer Can you please provide an example with more details like which actions you are talking in POST or maybe another question.Secretarial
D
3

http://www.django-rest-framework.org/api-guide/permissions/

as per above URL you have to write one custom permission class

class ExampleView(APIView):
    permission_classes = (MyCustomAuthenticated,)

Write your own logic using AllowAny or IsAuthenticated inside MyCUstomAuthenticated based on POST and GET

Dyne answered 5/6, 2016 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.