Building APIs with Django and Django REST Framework
Django REST Framework is a powerful toolkit for building RESTful APIs in Django. Views are the Python functions or classes that handle requests and return responses.
Django REST Framework provides generic views for common tasks, such as retrieving a list of objects, creating a new object, updating an existing object, and deleting an existing object. These views are designed to follow the principles of RESTful architecture.
In this tutorial, we are about to learn how to create a simple backend API using Django & DjangoRestFramework
Setup
Before we begin, please ensure that you have Python 3+ and PyCharm installed on your system. If PyCharm is not installed yet, you can download it from this link. PyCharm is a powerful Integrated Development Environment (IDE) used for programming in Python.
Start Project
Follow these steps to kick-start your Django project:
- Start a new project in PyCharm: Open PyCharm and click on
Create New Project
. Name your project asnotes
and make sure to select the Python interpreter as Python 3+. Ensure that a new virtual environment is created for this project. - Create a
requirements.txt
file: In the root directory of your project, create a new file and name itrequirements.txt
. In this file, add the following lines of code which specify the versions of Django and Django REST Framework we want to use:
django
djangorestframework
- Install the dependencies: Open your terminal/command prompt and navigate to your project directory where the
requirements.txt
file is located. Run the following command to install the required packages specified in therequirements.txt
file:
pip install -r requirements.txt
- This command tells pip (Python’s package installer) to install the versions of Django and Django REST Framework that we specified in our
requirements.txt
file. - Start a new Django project: In your terminal/command prompt, navigate to the directory where you want your Django project to reside. Run the following command:
django-admin startproject notes .
- This will create a new Django project named notes in the current directory.
Here’s a brief overview of the main files and directories:
manage.py
: A command-line utility that lets you interact with your project in various ways. It's a thin wrapper arounddjango-admin.py
that takes care of a couple of things for you.notes/
: This is the Python package for your project. It's the container for your project. Its name is the Python package name you’ll need to use to import anything inside it (e.g.notes.settings
).notes/settings.py
: Settings/configuration for this Django project. Django settings will tell you all about how settings work.notes/urls.py
: The URL declarations for this Django project; a “table of contents” of your Django-powered site. It's where you'll define the URL routes for your web application.notes/asgi.py
ornotes/wsgi.py
: An entry-point for ASGI-compatible web servers (for asynchronous programming) or WSGI-compatible web servers (for synchronous programming) to serve your project.
Now, your Django project is ready to be run. You can start your development server using python manage.py runserver
the command. However, note that at this point, while your project is set up, it doesn't do anything yet until you create your first app.
Create an application named as `src`
Apps are the building blocks of a Django project. Each Django project can contain multiple apps, and each app is a self-contained module that encapsulates the specific functionality of the project. For your notes
project, you might have an app to handle user authentication, another to manage the notes themselves, and so on. To create an app within your project, you would use the below command.
python manage.py startapp src
Adding the App to settings.py
and Setting Up the Directory Structure
After creating your Django app, make sure to add it to the INSTALLED_APPS
list in the settings.py
file. This will ensure that Django is aware of the app and its components:
# settings.py
INSTALLED_APPS = [
# ...
'src',
]
Next, delete all files from the src
directory and create the following Python packages:
src/models
src/views
src/serializers
python packages are folder with __init__.py files
Now, we will create a new Django model, serializer, and later on, a view for our notes app.
Creating the Notes Model
Inside the src/models
directory, create a new file named notes.py
and write the following code:
# src/models/notes.py
from django.db import models
class Notes(models.Model):
id = models.AutoField(primary_key=True, editable=False)
title = models.CharField(default="", max_length=500)
link = models.CharField(default="", max_length=200)
description = models.CharField(default="", max_length=500)
tag = models.CharField(default="others", max_length=200)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
def is_authenticated(self):
return True
def save(self, *args, **kwargs):
return super(Notes, self).save(*args, **kwargs)
def __unicode__(self):
return str(self.id)
class Meta:
db_table = 'notes'
app_label = 'src'
This model represents a note with a unique id
, title
, link
, description
, tag
, and timestamps for creation and modification. The is_authenticated
method returns True as a placeholder for actual authentication later on.
Don’t forget to add the notes
package to the __init__.py
file in the models
folder for export.
Creating the Notes Serializer
Inside the src/serializers
directory, create a new file named serializersnotes.py
and write the following code:
After setting up the Notes
model in the src/models/notes.py
file, the next step is to create a serializer for our model. Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON or other content types.
- Create the
notesserializers.py
file: Inside thesrc/serializers/
directory, create a new Python file namednotesserializers.py
. - Add the following code to the
serializersnotes.py
file:
from rest_framework import serializers
from src.models.notes import Notes
class NotesSerializer(serializers.ModelSerializer):
class Meta:
model = Notes
fields = '__all__'
This code first imports the necessary modules from Django REST Framework and our Notes
model. It then defines a NotesSerializer
class that inherits from serializers.ModelSerializer
. The ModelSerializer
class provides a shortcut that lets you automatically create a Serializer
class with fields that correspond to the model fields.
The Meta
class inside the NotesSerializer
class is a subclass that provides metadata to the NotesSerializer
class. Here we're telling Django REST Framework that we want to serialize all fields of the Notes
model.
- Add package to
__init__.py
for export: - Finally, make sure to export your
Notes
model and theNotesSerializer
in the__init__.py
file of their respective directories (i.e.,src/models/__init__.py
andsrc/serializers/__init__.py
). This will make them available when we importmodels
orserializers
elsewhere in our project.
For instance, in src/models/__init__.py
you might have:
from .notes import Notes
And in src/serializers/__init__.py
:
from .notesserializers import NotesSerializer
Now you’ve created a serializer for your Notes
model, which will allow Django REST Framework to convert the model instances into JSON format. This is a key step in creating RESTful APIs with Django and Django REST Framework.
Setting Up View
Create a new file notesview.py
inside src/views/
directory: In the src/views/
directory, create a new Python file named notesview.py
. Write the following code in notesview.py
:
from rest_framework import generics, mixins
from src.models.notes import Notes
from src.serializers.notesserializers import NotesSerializer
class NotesView(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin,
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin):
serializer_class = NotesSerializer
queryset = Notes.objects.all()
def get(self, request, pk=None):
if pk:
return self.retrieve(request, pk)
else:
return self.list(request)
def post(self, request):
return self.create(request)
def put(self, request, pk=None):
return self.update(request, pk)
def delete(self, request, pk=None):
return self.destroy(request, pk)
We’ve defined four methods corresponding to the four HTTP methods:
- `get`: retrieves a list of `Notes` objects and returns them in JSON format.
- `post`: creates a new `Notes` object and returns it in JSON format if the request data is valid.
- `put`: updates an existing `Notes` object with the specified primary key (pk) and returns it in JSON format if the request data is valid.
- `delete`: deletes an existing `Notes` object with the specified primary key (pk) and returns a 204 status code if successful.
Add this view to urls.py
:
from django.urls import path
from src.views.notesview import NotesView
urlpatterns = [
path('notes/', NotesView.as_view(), name='notes'),
path('notes/<int:pk>/', NotesView.as_view(), name='note'),
]
In this file, we’re defining two URLs — one for listing and creating notes (/notes/
) and another for updating and deleting specific notes (/notes/<int:pk>/
), where <int:pk>
is the primary key (id) of a note.
Migrate
To reflect the changes we made in the database, we need to create migrations and apply them. Migrations are Django’s way of propagating changes made to your models (adding a field, deleting a model, etc.) into your database schema.
Create Migrations: Run the following command in your terminal to create migrations for your src
app:
python manage.py makemigrations src
This tells Django to create new migrations based on the changes detected in your models. Next, apply the migrations using this command:
python manage.py migrate
This command applies migrations and manages the database schema. Your database is now ready to be used with your Django app.
And with that, your Django REST API is ready! Your Django project is now set up to handle CRUD (Create, Retrieve, Update, Delete) operations for notes via its REST API.
Add Localhost to the allowed domain in settings.py
Open notes/settings.py and add localhost
..
ALLOWED_HOSTS = ["localhost"]
...
Start the server:
Finally, to start your Django server, run the following command:
Finally, to start your Django server, run the following command:
python manage.py runserver 0.0.0.0:8000
Your Django project is now live and can be accessed at http://localhost:8000/notes.
Now that your Django project is up and running, you might want to test your API endpoints. You can do this through a variety of tools such as the Django REST Framework’s built-in web-browsable API, the Postman tool, or via curl
commands in your terminal.
Remember to use different HTTP methods (GET, POST, PUT, DELETE) to test the various functionalities of your REST API. For instance, you could use a GET request to http://localhost:8000/notes/
to retrieve all notes, or a POST request to the same URL to create a new note.
Watch complete tutorial video
Resources
To learn more about Django, Django REST Framework, and building REST APIs, you can refer to the following resources:
- Django Documentation: The official Django documentation is a comprehensive resource that covers everything about Django.
- Django REST Framework Documentation: The official Django REST Framework documentation covers all aspects of the framework.
- Django for APIs: A book about building APIs with Django and Django REST Framework.
- Building APIs with Django and Django Rest Framework: A step-by-step tutorial to building a polls API.
Remember, the best way to learn is by doing. Continue building, refining, and testing your Django projects, and soon enough, you’ll become proficient in using Django and Django REST Framework for building powerful web applications and APIs.
About the Author
Author Name: Saurabh Pandey
Saurabh Pandey is a passionate Software Engineer from India. With years of experience in the industry, Saurabh has honed his skills in various programming languages and technologies, allowing him to effectively lead and contribute to complex projects.
To connect with Saurabh and learn more about his work, you can visit his LinkedIn profile at https://www.linkedin.com/in/dextrop/.