How To Create An API with Django REST Framework Quickly

Viktor Nagornyy
Powered by Django
Published in
6 min readApr 4, 2023

Django REST Framework (DRF) is a powerful and flexible Django package that makes building web APIs in your Django projects easy.

I use Pegasus SaaS boilerplate in my projects, which bundles DRF out of the box. This way, I don’t have to do much work to get started. It even includes API passwords per user, so I can offer an API to users if needed.

In this tutorial, I’ll walk you through adding DRF to your Django project, creating an example POST endpoint with Basic Authentication, and an example GET endpoint without any authentication.

Before we begin

Before we begin, this tutorial assumes a few things:

  1. Django is already installed using pipenv
    (not yet? Learn how on Windows or Docker).
  2. You’re using a code editor (e.g., Visual Studio Code).

With these prerequisites met, we can create an API using DRF.

Step 1: Install Django REST Framework

First, let’s install Django REST Framework using pipenv. Open your terminal or command prompt and enter the following command:

pipenv install djangorestframework

This command will add DRF to your Pipfile and install it within your project’s virtual environment.

Remember to use pipenv run or pipenv shell when executing commands like python manage.py runserver to ensure you're using the virtual environment created by Pipenv.

Step 2: Add DRF to your Django project

Now, open your Django project’s settings.py file and add rest_framework to the INSTALLED_APPS list:

INSTALLED_APPS = [
# ...
'rest_framework',
]

Step 3: Configure DRF settings

In your project’s settings.py file, add the following code to configure Django REST Framework:

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
}

This configuration sets the default permission to allow any requests and enables Basic Authentication as the default authentication class.

The DEFAULT_PERMISSION_CLASSES setting within the REST_FRAMEWORK the configuration defines the default permission classes applied to your Django REST Framework views.

The rest_framework.permissions.AllowAny class is specified as the default permission class. This means that, by default, any client (authenticated or not) can access the views in your Django REST Framework project unless the views explicitly specify different permission classes.

AllowAny is a built-in permission class in DRF, granting access to any user, regardless of their authentication status. If you want to restrict access to your API views, use other built-in permission classes or create custom permission classes. Some built-in alternatives include:

  • rest_framework.permissions.IsAuthenticated: Grants access only to authenticated users.
  • rest_framework.permissions.IsAdminUser: Grants access only to users with is_staff attribute set to True.
  • rest_framework.permissions.IsAuthenticatedOrReadOnly: Grants read access to everyone but restricts write access to authenticated users.

Remember that you can always override the default permission classes per view by setting the permission_classes attribute in your view classes.

Step 4: Create an example model

For this tutorial, let’s create a simple model named “Message.” You can skip this step if you already have your models in place.

In your Django app directory, create a models.py file with the following:

from django.db import models

class Message(models.Model):
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.content

Don’t forget to run the following commands to create the corresponding database table:

python manage.py makemigrations
python manage.py migrate

Remember, these commands must be run inside the virtual environment. If you’re getting an error, activate virtual environment pipenv shell.

Step 5: Create a serializer

Serializers allow you to convert complex data types, such as Django models, into Python data types that can be easily rendered into JSON or other content types.

Create a serializers.py file in your app’s directory with the following:

from rest_framework import serializers
from .models import Message

class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
fields = '__all__'

Don’t forget we must import the “Message” model to make it available to the serializer. If you’re getting a model-related error, check your imports.

In a Django REST Framework serializer, the fields attribute is used to specify which fields of the model should be included in the serialized representation of the object. The fields attribute is typically defined within the Meta class of the serializer.

When you set fields = '__all__', it means that all fields defined in the associated model will be included in the serialized representation. In other words, the serializer will expose all fields of the model when converting the model instance to JSON or other content types.

Using fields = '__all__' is a convenient way to include all fields without explicitly listing them. However, if you want to expose only a subset of the model fields, you can provide a tuple or list of field names like this:

fields = ('content', 'created_at')

Step 6: Create the views

Now, let’s create two views — one for the POST endpoint with Basic Authentication and another for the GET endpoint without authentication.

This is where we combine the serializers and data in the models.

In your app’s directory, create a views.py file with the following:

from rest_framework import generics, permissions
from .models import Message
from .serializers import MessageSerializer

class MessageCreateView(generics.CreateAPIView):
queryset = Message.objects.all()
serializer_class = MessageSerializer
permission_classes = [permissions.IsAuthenticated]
http_method_names = ['post']

class MessageListView(generics.ListAPIView):
queryset = Message.objects.all()
serializer_class = MessageSerializer
http_method_names = ['get']

As mentioned in Step 3, we’re changing permission_classes for the view that requires authentication, the view without authentication will continue using the default permission classes.

By specifying the http_method_names attribute, we explicitly allow only POST requests for the MessageCreateView and only GET requests for the MessageListView. This ensures that other HTTP methods, such as PUT or DELETE, are not allowed for these endpoints.

Step 7: Create the URLs

Finally, we’ll map the views to their corresponding URLs.

In your app’s directory, create a urls.py file with the following:

from django.urls import path
from . import views

urlpatterns = [
path('messages/', views.MessageListView.as_view(), name='message-list'),
path('messages/create/', views.MessageCreateView.as_view(), name='message-create'),
]

Now, include the app’s URLs in the project’s urls.py file. This is a different urls.py file that you can find in your project’s root directory:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('your_app_name.urls')),
]

Replace your_app_name with the name of your custom Django app.

That’s it! You’ve successfully added Django REST Framework to your project and created two example endpoints:

  1. A POST endpoint with Basic Authentication at /api/messages/create/ for creating new messages.
  2. A GET endpoint without authentication at /api/messages/ for listing all messages.

To test your API, you can use tools like Postman, HTTPie, curl, or (what I use) a free VS Code extension called Thunder Client.

Remember, you must provide a valid username and password when testing the POST endpoint since it uses Basic Authentication.

Basic authentication

When using Basic Authentication with Django REST Framework, you don’t set the username and password directly in your code. Instead, DRF relies on Django’s built-in authentication system, which uses the User model from the django.contrib.auth.models module to manage user accounts, including their usernames and passwords.

To use Basic Authentication with DRF, you should first create user accounts in your Django project. You can do this in several ways:

  1. Django Admin Site: If you have Django’s admin site enabled, you can create, edit, and manage user accounts through the web interface by visiting /admin/ in your project.
  2. Registration Views: You can create user registration views and templates in your Django project, allowing users to sign up with their desired usernames, emails, and passwords. This involves creating a form for user registration, handling form submissions, and creating new user instances upon form validation.
  3. Django Shell: You can use Django’s shell to create user accounts through the command line. To open the Django shell, run the following command in your terminal:
python manage.py shell

Once the shell is open, you can create a new user with the following:

from django.contrib.auth.models import User
user = User.objects.create_user('username', 'email@example.com', 'password')
user.save()

Replace username, email@example.com, and password with the new user account's desired username, email, and password.

When making requests to the API using Basic Authentication, clients must provide the username and password in the Authorization header of the HTTP request. The format for the Authorization header is:

Authorization: Basic {base64_encoded_credentials}

{base64_encoded_credentials} is a Base64-encoded string of the format "username:password".

For example, using curl to request an API endpoint that requires Basic Authentication:

curl -u username:password https://example.com/api/messages/create/

New To Django?

If you’re new to Django, as I was, you may be looking for good resources to learn how to use Django to build apps. The best resources that helped me learn Django with easy-to-follow instructions and code are the three ebooks written by William S. Vincent (he keeps them up-to-date):

Django for Beginners laid a solid foundation for me to pick up all other Django (and Python) concepts. Start with that ebook. That’s what I did.

If you want to be notified of new stories related to Django, follow Powered by Django here on Medium, or you can follow me to learn more about digital marketing in addition to Django.

This article includes affiliate links.

--

--

Viktor Nagornyy
Powered by Django

📈 Marketing consultant. 14 years helping biz generate leads & sales. Open source advocate. Sign up for my marketing coaching newsletter ➡️ inboundmethod.com/m