Installing Django REST Framework and setting up the project
This series builds a real API — a task manager, with users, permissions, filtering, pagination, and documentation — across 22 parts using Django REST Framework (DRF), the library almost every production Django API is built on. It assumes a Django project exists but not DRF specifically; if you haven't set up a Django project before, the Django from scratch series covers that ground first. This part just gets DRF installed and the one model the whole series revolves around defined.
Installing DRF
mkdir taskapi && cd taskapi
python3 -m venv venv
source venv/bin/activate
pip install django djangorestframework
django-admin startproject taskapi .
python manage.py startapp tasksDRF is a separate package from Django itself — it's a toolkit built on top of Django, not a replacement for any part of it. Everything from serializers to viewsets in this series is DRF-specific; the underlying model layer, migrations, and admin are exactly the Django you already know.
Registering both apps
# taskapi/settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"tasks",
]rest_framework has to be in INSTALLED_APPS for DRF's own features to work — the browsable API (part 18) and its template tags specifically depend on it being registered like any other app.
The Task model
# tasks/models.py
from django.db import models
from django.conf import settings
class Task(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(blank=True)
completed = models.BooleanField(default=False)
due_date = models.DateField(null=True, blank=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="tasks")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_at"]
def __str__(self):
return self.titlepython manage.py makemigrations tasks
python manage.py migrate
python manage.py createsuperuserNothing here is DRF-specific — it's the same models.Model pattern from the Django from scratch series. That's deliberate: DRF doesn't change how you define data, only how you expose it. Register Task in tasks/admin.py (admin.site.register(Task)) and create a few test tasks through the admin before part 2, which needs real data to actually serialize.
Forgetting rest_framework in INSTALLED_APPS and getting a confusing TemplateDoesNotExist error the first time the browsable API tries to render — it's not a missing template, it's DRF not being registered.
FAQ
Do I need DRF for every Django project, even one with no API? No — DRF exists specifically for exposing data as JSON (or another API format) to something other than Django's own templates: a mobile app, a separate frontend, another service. A Django project that only renders its own HTML pages, like the Django from scratch series' blog, has no need for it.
Could I build this same API with plain Django views instead of DRF?
Yes, technically — a plain view can return JsonResponse manually. DRF's actual value is everything around that: serializers for validation and format conversion, authentication and permission classes, the browsable API, and generic views that remove most of the boilerplate a hand-rolled JSON view would otherwise repeat for every model.
Is settings.AUTH_USER_MODEL different from just importing User directly?
Yes, and it matters here specifically — settings.AUTH_USER_MODEL resolves to whatever user model the project actually uses, including a custom one substituted in later. Importing django.contrib.auth.models.User directly hardcodes Django's default, which breaks if a project ever switches to a custom user model — a real, common pattern in a growing app.