How to add permissions in an API Django REST framework

In the Django REST framework, there are different ways of adding access control to a particular view (route) or all the views (routes).

Examples of permissions that are mostly in Django REST framework:

  • AllowAny
  • IsAuthenticated
  • IsAdminUser
  • IsAuthenticatedOrReadOnly

AllowAny

The AllowAny permission class will allow unrestricted access, irrespective of whether the request was authenticated or unauthenticated.

REST_FRAMEWORK ={
# anyone can visit it and input data
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny'
]
}

IsAuthenticated

The IsAuthenticated permission class denies unauthenticated users to use the APIs for any operations. This ensures APIs accessibility only to registered users and logged-in users.

REST_FRAMEWORK ={
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
]
}

IsAuthenticatedOrReadOnly

IsAuthenticatedOrReadOnly grants edit access to only authenticated users and read only access to unauthenticated users. For example:

```py
REST_FRAMEWORK ={
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly'
]
}
```

IsAdminUser

The IsAdminUser permission class will allow permission to users whose user.is_staff is True. It ensures access is granted to only administrators that have been granted access through IAM.

REST_FRAMEWORK ={
# only staff users can see the data and input data
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAdminUser'
]
}

Installation

pip install pipenv
pipenv shell
pipenv install django

Also install restframework:

pipenv install djangorestframework

The ./ allows us to install the Django file (restframe) in the same directory, instead of creating a new one.

django-admin startproject restframe ./

python manage.py startapp codebase
python manage.py migrate

python manage.py runserver

Go to settings.py and do this

settings.py

# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#the app
'languages',
#restframework
'rest_framework',
]
# adding the permission class
# it will serve as default permission class
REST_FRAMEWORK ={
#Authenticated or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly'
]
}

In the codebase app folder, go to:

models.py

from django.db import models
# Create your models here.
# to know the paradigm of the programming language(e.g OOP)
class Paradigm(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
# the programming language
class Language(models.Model):
name = models.CharField(max_length=50)
#referencing the Paradigm Model
# models.CASCADE means if the Paradigm is deleted
# the Language model data related to the partcular deleted paradigm will also be deleted
paradigm = models.ForeignKey(Paradigm , on_delete=models.CASCADE)
def __str__(self):
return self.name
# name of any programmer
class Programmer(models.Model):
name = models.CharField(max_length=50)
# referencing the Langauge Model
# ManyToManyField allows a user to select more than one programming language
languages = models.ManyToManyField(Language)
def __str__(self):
return self.name

The paradigm model allows us to know the paradigm of a particular programming language: for example, if it is object orientated programming language (OOP).

The language model is to list different programming languages.

The programmer model is to know the names of the programmer and the language/languages they know.

Foreign key is used for creating and working with relationships between tables in relational databases. It is used to link different models to each other.

admin.py

from django.contrib import admin
from .models import Language, Programmer,Paradigm
admin.site.register(Language)
admin.site.register(Programmer)
admin.site.register(Paradigm)

Create a file and name it serializer.py. Here, we will serialize the model input to be able to output it in Json format. It basically translates Django to other formats.

Serializers allow complex data such as querysets to be converted to native Python datatypes that can be rendered into JSON, XML, etc.

serializer.py

from rest_framework import serializers
from .models import Language,Paradigm,Programmer
#hyperlinkedmodelserializer makes it possbile for it to have a url link
class LanguageSerializer(serializers.HyperlinkedModelSerializer):
# used to change the behaviour of a class or Model
class Meta:
# referencing the language model
model = Language
# listing the fields that will be displayed
fields = [
"id",
'url',
"name",
"paradigm"
]
class ParadigmSerializer(serializers.HyperlinkedModelSerializer):
# used to change the behaviour of a class or Model
class Meta:
# referencing the paradigm model
model = Paradigm
# listing the fields that will be displayed
fields = [
"id",
'url',
"name",
]
class ProgrammerSerializer(serializers.HyperlinkedModelSerializer):
# used to change the behaviour of a class or Model
class Meta:
# referencing the programmer model
model = Programmer
# listing the fields that will be displayed
fields = [
"id",
'url',
"name",
"languages"
]

views.py

This file is used to create functions or classes that visualize how a route will operate.

from django.shortcuts import render
# import the serializers class
from .serializer import LanguageSerializer, ParadigmSerializer, ProgrammerSerializer
from rest_framework import viewsets, permissions
from .models import Language, Paradigm,Programmer
# Create your views here.
class LanguageView(viewsets.ModelViewSet):
queryset = Language.objects.all()
# initializing the serializer
serializer_class = LanguageSerializer
#it will automately overide the default permissions that is in settings.py
permission_classes = (permissions.AllowAny,)
class ParadigmView(viewsets.ModelViewSet):
queryset = Paradigm.objects.all()
# initializing the serializer
serializer_class = ParadigmSerializer
#it will automately overide the default permissions that is in settings.py
permission_classes = [permissions.IsAdminUser]
class ProgrammerView(viewsets.ModelViewSet):
queryset = Programmer.objects.all()
# initializing the serializer
serializer_class = ProgrammerSerializer

In the restframe folder, in the urls.py file, do this:

urls.py

from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# including the codebase urls.py file
path('', include('codebase.urls'))
]

Then, in the ‘codebase’ folder, create a file and name it urls.py.

urls.py

from django.urls import path, include
#import django restframework router
from rest_framework import routers
from . import views
# initializing the router
router = routers.DefaultRouter()
# register each views or route
router.register('languages', views.LanguageView)
router.register('paradigms', views.ParadigmView)
router.register('programmers', views.ProgrammerView)
urlpatterns = [
path('api-auth', include('rest_framework.urls', namespace='rest_framework')),
path('', include(router.urls)),
]

Then, run the following commands:

python manage.py makemigrations

python manage.py migrate

In case you want to create a super-user, run the following command:

python manage.py createsuperuser

After it, run:

python manage.py runserver

Then, go to http://127.0.0.1:8000/admin and login in order to access the admin panel.

Or, go to http://127.0.0.1:8000/ to access the homepage.

Free Resources