Returning custom message when a permission is denied in DRF

when permission isn't granted, I will raise a exception which custom response. It works on djangorestframewor(3.10.1) and django(2.2.3).

from rest_framework.permissions import BasePermission
from rest_framework.exceptions import APIException
from rest_framework import status


class IsLogin(BasePermission):
    """
    Allows access only to authenticated users.
    """

    def has_permission(self, request, view):
        if request.email:
            return True
        raise NeedLogin()


class NeedLogin(APIException):
    status_code = status.HTTP_403_FORBIDDEN
    default_detail = {'error': True, 'message': 'need login'}
    default_code = 'not_authenticated'

Building on Aysennoussi’s answer:

from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view): 
        if request.user.has_expired:
            self.message = “Your account has expired.”
            return False
        elif request.user.has_access:
            return True
        else:
            return False


From DRF

you can simply add message attribute.

from rest_framework import permissions

class IsSuperUserPermission(permissions.BasePermission):
    message = 'User is not superuser'

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

It will return a dict with key detail, something like this:

{
    'detail': 'User is not superuser'
}

But what if you want for example that the dict key not to be detail but errors for example, it will be the same how return errors DRF.

We can set message attribute not to string but to dict, something like this:

class IsSuperUserPermission(permissions.BasePermission):
    message = {'errors': ['User is not a superuser']}

    def has_permission(self, request, view):
        self.message['errors'].clear()
        return self.request.user.is_superuser

In this case the error will be:

{
    'errors': ['User is not a superuser']
}

Since DRF 3.2.0, You only have to add a message attribute :

from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view): 

See from DRF documentation: http://www.django-rest-framework.org/api-guide/permissions/#custom-permissions