Create a Simple Movies and Actors API with Django REST Framework (DRF)

Updated

Build a Movies and Actors API with Django REST Framework. Learn serializers, API views, and how DRF authentication works.

In this tutorial, we will create a simple API for managing movies and their actors using Django REST Framework (DRF). I will go through every step, from setting up the project to implementing authentication and creating an open endpoint accessible to anyone. Along the way, I'll explain what serializers are and how API views differ from regular Django views.


Step 1: Set Up Your Django Project

Start by creating a new Django project and app.

# Install Django and Django REST Framework
pip install django djangorestframework

# Create the project
django-admin startproject movies_project

# Navigate into the project directory
cd movies_project

# Create the movies app
python manage.py startapp movies

Add the movies app and rest_framework to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', # Added
    'movies', # Added
]

Step 2: Define Models

Let's create 2 models for Movie and Actor in movies/models.py.

from django.db import models

class Actor(models.Model):
    name = models.CharField(max_length=100)
    birth_date = models.DateField()
    # Add more fields here

    def __str__(self):
        return self.name

class Movie(models.Model):
    title = models.CharField(max_length=100)
    release_year = models.IntegerField()
    actors = models.ManyToManyField(Actor)
    # Add more fields here

    def __str__(self):
        return self.title

Now let's run migrations to create the database tables for the models we just created:

python manage.py makemigrations
python manage.py migrate

Step 3: Creating Serializers

A serializer in Django REST Framework is responsible for converting complex Python objects (like Django models) into JSON (or another data format) that can be sent over the internet. It also validates incoming data and converts it into Python objects that your app can process.

Think of a serializer as the bridge between your database and the JSON data your API sends and receives.

Here's how we can create serializers for our models in movies/serializers.py:

from rest_framework import serializers
from .models import Actor, Movie

class ActorSerializer(serializers.ModelSerializer):
    class Meta:
        # The referenced model
        model = Actor
        # list of fields that need serialization
        fields = ['id', 'name', 'birth_date']

class MovieSerializer(serializers.ModelSerializer):
    # Define related field serializer
    actors = ActorSerializer(many=True, read_only=True)

    class Meta:
        # The referenced model
        model = Movie
        # list of fields that need serialization
        fields = ['id', 'title', 'release_year', 'actors']

Explanation

  • ModelSerializer: A shortcut for creating serializers directly from Django models.
  • Meta class: Specifies which model to use and which fields to include in the JSON response.
  • Nested Serialization: For movies, we included actors as nested objects using ActorSerializer. This makes the API response more informative.

Step 4: API Views

API views in DRF are different from regular Django views. While Django views handle rendering HTML templates for web pages, API views focus solely on returning and processing data (e.g., JSON). They are designed for building RESTful APIs.

Here's how API views differ:

  • No Templates: API views return raw data, not rendered HTML pages.
  • HTTP Methods: They handle HTTP verbs like GET, POST, PUT, and DELETE directly.
  • Serialization: They use serializers to format the data instead of rendering templates.

We use viewsets to simplify our API views. A viewset combines logic for multiple actions (like listing, creating, updating, and deleting) in one class.

In movies/views.py, we can create the views for actors and movies. For demonstration purposes, let's make the actor view only allow authenticated users.

from rest_framework import viewsets
from .models import Movie, Actor
from .serializers import MovieSerializer, ActorSerializer
from rest_framework.permissions import IsAuthenticated, AllowAny

class ActorViewSet(viewsets.ModelViewSet):
    queryset = Actor.objects.all()
    serializer_class = ActorSerializer
    permission_classes = [IsAuthenticated]  # Only authenticated users

class MovieViewSet(viewsets.ModelViewSet):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer
    permission_classes = [AllowAny]  # Open to everyone

Explanation

  • ActorViewSet: Requires authentication to access.
  • MovieViewSet: Open to all users, thanks to the AllowAny permission.
  • ModelViewSet: Automatically provides CRUD operations (Create, Read, Update, Delete) for the model.

Step 5: Configure URLs

Set up routing for the API in movies/urls.py:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ActorViewSet, MovieViewSet

router = DefaultRouter()
router.register(r'actors', ActorViewSet)
router.register(r'movies', MovieViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

Include the app URLs in the project's urls.py:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('movies.urls')),  # API endpoints
]

Step 6: Add Authentication Defaults

In settings.py, enable authentication:

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

This setup ensures that endpoints are restricted to authenticated users unless otherwise specified.


Step 7: Populate the Database

Use the Django admin panel or shell to add some example movies and actors.

Example Data

  • Movies: The Shawshank Redemption, Forrest Gump
  • Actors: Tim Robbins, Morgan Freeman, Tom Hanks

Step 8: Test the API

Endpoints

  • Movies Endpoint (/api/movies/): Open to everyone.
  • Actors Endpoint (/api/actors/): Requires authentication.

You can test the API using tools like Postman or curl.


Conclusion

We've created a simple API with Django REST Framework. You've learned how serializers convert models into JSON, how API views differ from regular views, and how to set up authentication. From here, you can expand your API with additional features like filtering, user roles, and pagination.

More posts in Python