Getting started with Django and REST Framework

Utkarsh Goel
5 min readMar 22, 2021

In this article, I want to cover a topic I’ve been revising from university days: Django (we did the Software Engineering course and Django was a requirement as a part of the tech stack). This article will try to help people get up to speed with using Django and Django REST framework.

If you follow along, we will build a small Django project, with as little code as possible to have a REST API that can do CRUD on a data model easily.

Just a quick note: Whenever I work on a Python project, I make a virtual environment, but I’ll leave that decision to you.

Why wouldn’t you use a virtual environment?

Let’s get started with the basics. To create a Django project, you should have Django installed:

pip install django

Now, you’ll be able to initialise a Django project. I’m gonna call my project myProject.

django-admin startproject myProject

You should have this

.
|____myProject
| |____asgi.py
| |______init__.py
| |____settings.py
| |____urls.py
| |____wsgi.py
|____manage.py

We have a Django project. If you’ve done some homework on Django before starting out and reading this article, you would know that in Django, we create applications, in which we have data models, views, etc. That makes up for all the functionality of our backend server (Django can help build web pages as well but this article will only focus on making a REST API).

Something I personally like to do when getting started with a Django project, before anything else I initialise my Django admin and create a superuser so I can log in to it. To do that:

python manage.py migrate

Now you’ll be able to create a superuser:

python manage.py createsuperuser

It will prompt you to enter a username, email and password. You will use the same credentials to log in to django admin.

I quickly realise that I should drop this advise that if you do not know what I’m talking about when I say “Django admin”, please look it up. You should be able to access it at: http://localhost:8000/admin when you start your Django server. Which brings me to:

python manage.py runserver

The above command will run your Django server. It has all the hot-reloading shabang.

http://localhost:8000/admin

From here onwards, we have to set a goal in mind. Let’s say that our Django application manages student records. This application needs to create, read, update and delete student records. We need a REST API to do that.

So we create a application first:

django-admin startapp students

This gives us a students folder:

.
|____myProject
| |____asgi.py
| |______init__.py
| |______pycache__
| | |____settings.cpython-36.pyc
| | |____wsgi.cpython-36.pyc
| | |______init__.cpython-36.pyc
| | |____urls.cpython-36.pyc
| |____settings.py
| |____urls.py
| |____wsgi.py
|____db.sqlite3
|____students
| |____migrations
| | |______init__.py
| |____models.py
| |______init__.py
| |____apps.py
| |____admin.py
| |____tests.py
| |____views.py
|____manage.py

The models.py will contain the Student data model.

from django.db import modelsclass Student(models.Model):
student_id = models.CharField(max_length=10)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
profile_picture = models.ImageField(upload_to="media/images/")

Add this to Django admin by registering it with admin:

students/admin.py:

from django.contrib import admin
from .models import Student
admin.site.register(Student)

myProject/settings.py:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'students.apps.StudentsConfig'
]

Now, lets migrate the database, makemigrations first, then migrate:

python manage.py makemigrations

python manage.py migrate

Django admin will now have Student data model.

Time to take a break….

According to our goal, the next task is to make a REST API. We use the django rest framework for it.

pip install djangorestframework

Now “django rest framework” is long to write, so I’m just gonna call it drf from now.

First, lets add drf to INSTALLED_APPS

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'students.apps.StudentsConfig',
'rest_framework'
]

DRF requires us to make ViewSet for our data model to do operations on it. We do this by defining it in students/views.py , and serializer in students/serializers.py .

from rest_framework import serializers
from .models import Student
class StudentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Student
fields = ['student_id', 'first_name', 'last_name', 'profile_picture']

students/views.py:

from django.shortcuts import render
from rest_framework import viewsets
from rest_framework import permissions
from .serializers import StudentSerializer
from .models import Student
class StudentViewSet(viewsets.ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer

To do operations on Student model, we need an endpoint where we can send requests. Here comes the urls.py .

...
from django.urls import path, include
from rest_framework import routers
from students.views import StudentViewSet
router = routers.SimpleRouter()
router.register('courses', StudentViewSet)
urlpatterns = [
path('', include(router.urls)),
...

You should have this now at http://localhost:8000/students:

Does everything work? almost.

One last small thing is the image. You’ll notice that images don’t load just yet. There is a little trick for it.

Add these to myProject/settings.py

...
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
...

To resolve the media URLS, you will need to make a change in urls.py

from . import settings
from django.contrib.staticfiles.urls import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
...
urlpatterns = [
...,
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Note that the urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) has been written separately.

Django should support media URLS now.

And that is a wrap!

Got further questions?

Tweet at me: javachipd (https://twitter.com/javachipd)
My webpage: https://utkarshgoel.dev

--

--