Permissions & Access Control in Django REST Framework (DRF)
Permissions and access control in Django REST Framework (DRF) allow you to secure your APIs by defining who can access, modify, or delete resources. It provides various permission classes to handle authentication and authorization at different levels.
Default Permission Classes
By setting default permission classes in your settings.py, you can enforce a global access policy across your entire API.
Settings Update
# bookstore/settings.py
REST_FRAMEWORK = {
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’, # Only authenticated users can access the API
]
}
To make an API accessible through the browser or tools like Postman, we need to map the ViewSet (like BookViewSet) to a URL.
Normally, we use a list called urlpatterns to define each path manually. But for ViewSets, there’s a better way — using DRF’s routers.
Explanation:
- Setting IsAuthenticated as the default permission ensures that only authenticated users can access any view in your API.
See below endpoint after adding the permission it looks:
- This applies to all views unless overridden explicitly.
- You only be able to see the view in your API if you have logged in.
Customizing Permissions
DRF allows you to create custom permission classes to implement more granular control over your APIs.
Creating a Custom Permission Class
# books/permissions.py (Create this file)
from rest_framework import permissions
class IsAdminOrReadOnly(permissions.BasePermission):
“””
Custom permission to only allow admin users to delete objects.
“””
def has_permission(self, request, view):
# Allow read-only requests for everyone (GET, HEAD, OPTIONS)
if request.method in permissions.SAFE_METHODS:
return True
# Allow delete only if the user is an admin
return request.user.is_superuser
Explanation:
- permissions.SAFE_METHODS refers to read-only requests (GET, HEAD, OPTIONS).
- Non-admin users can view resources, but only admins (is_superuser) can delete them.
Applying Custom Permission to Views
Custom permissions can be applied to individual views to enforce specific access rules.
# books/views.py (Import the custom permission)
from .permissions import IsAdminOrReadOnly
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
class BookDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [IsAdminOrReadOnly] # Applying custom permission
Explanation:
- BookDetailView allows retrieving, updating, or deleting a Book instance.
- The custom permission IsAdminOrReadOnly restricts deletion to admin users only.
Testing Custom Permission with Non-Admin User
1. Follow the prompts to create an admin user.
In your Django project, create a regular user (admin) using the command line:
python manage.py createsuperuser
After creating a user ,Click on John user and uncheck the staff status and superuser status.
Note:We are unchecking staff status and superuser status for testing the custom permission as non admin user.
Start the Server
python manage.py runserver
- Testing Endpoints as Non-Admin Users
- Log out from the admin panel.
- Visit to an Endpoint http://127.0.0.1:8000/api/books/2/.and test the request
For example, to test a GET request:
Paste the endpoint in postman http://127.0.0.1:8000/api/books/2/.Like below:
If you send a PUT request you can see it not updated
Explanation
- This method allows you to test various permissions and endpoints without relying on the Browsable API.
- Works well if you are building a headless API or if the browsable API is disabled.
Summary
- Default Permissions: Set globally via settings.py.
- Custom Permissions: Defined by creating classes inheriting from permissions.BasePermission.
- Applying Permissions: Applied to views using the permission_classes attribute.
How Does It Work? (Step-by-Step Execution)
1. Define Default Permissions (Global Setting)
- In settings.py, set the default permission class to IsAuthenticated.
- This ensures that only authenticated users can access the entire API unless overridden at the view level.
2. Create Custom Permission Class (For Specific Control)
- Define a new permission class IsAdminOrReadOnly in permissions.py.
- Allow read-only access to everyone (GET, HEAD, OPTIONS).
- Allow deletion only if the user is an admin (is_superuser)
3. Apply Custom Permission to View
- Apply IsAdminOrReadOnly to BookDetailView via the permission_classes attribute.
Exercise:
- Apply IsAuthenticated permission to the StudentViewSet.
- Try accessing the API:
- Without logging in — should get 403 Forbidden.
- With token/login — should get access.