Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It’s well-suited for creating powerful web applications and APIs. In this comprehensive guide, we will walk through the steps to create a REST API with Django using Django REST framework (DRF), covering everything from setting up the environment to deploying the application.
Table of Contents
- Introduction to REST APIs
- Setting Up the Django Environment
- Creating a New Django Project
- Setting Up Django REST Framework
- Creating Your First Endpoint
- Handling Different HTTP Methods
- Using Django Models and Serializers
- Implementing Authentication
- Error Handling and Validation
- Testing Your API
- Documentation with Swagger
- Deployment
- Conclusion
1. Introduction to REST APIs
REST (Representational State Transfer) is an architectural style for designing networked applications. It relies on a stateless, client-server, cacheable communication protocol — the HTTP. RESTful applications use HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources, which can be represented in formats like JSON or XML.
Key Concepts
- Resource: Any object that can be accessed via a URI.
- URI (Uniform Resource Identifier): A unique identifier for a resource.
- HTTP Methods: Common methods include GET, POST, PUT, DELETE.
2. Setting Up the Django Environment
Installing Django and Django REST Framework
First, ensure you have Python installed. You can download it from the official website. Then, install Django and Django REST framework using pip:
pip install django djangorestframework
Creating a Virtual Environment
It’s good practice to create a virtual environment for your project to manage dependencies:
python -m venv myenv
source myenv/bin/activate # On Windows use `myenv\Scripts\activate`
3. Creating a New Django Project
Starting a New Project
Create a new Django project with the following command:
django-admin startproject myproject
cd myproject
Starting a New App
In Django, applications are components of your project. Create a new app within your project:
python manage.py startapp myapp
Adding the App to INSTALLED_APPS
Edit myproject/settings.py
to include myapp
and rest_framework
in the INSTALLED_APPS
list:
INSTALLED_APPS = [
...
'rest_framework',
'myapp',
]
4. Setting Up Django REST Framework
Configuring Django REST Framework
Add basic settings for Django REST framework in myproject/settings.py
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
}
5. Creating Your First Endpoint
Defining Models
In myapp/models.py
, define a simple model:
from django.db import modelsclass Item(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def __str__(self):
return self.name
Making Migrations
Create the database schema for the models:
python manage.py makemigrations
python manage.py migrate
Creating Serializers
Serializers define how the model instances are converted to JSON. Create a file myapp/serializers.py
:
from rest_framework import serializers
from .models import Itemclass ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ['id', 'name', 'description']
Defining Views
Create views to handle API requests in myapp/views.py
:
from rest_framework import generics
from .models import Item
from .serializers import ItemSerializerclass ItemListCreate(generics.ListCreateAPIView):
queryset = Item.objects.all()
serializer_class = ItemSerializer
class ItemDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Item.objects.all()
serializer_class = ItemSerializer
Adding URL Patterns
Define URL patterns to route requests to the views in myapp/urls.py
:
from django.urls import path
from .views import ItemListCreate, ItemDetailurlpatterns = [
path('items/', ItemListCreate.as_view(), name='item-list-create'),
path('items/<int:pk>/', ItemDetail.as_view(), name='item-detail'),
]
Include these URL patterns in the project’s main urls.py
:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('myapp.urls')),
]
6. Handling Different HTTP Methods
List and Create (GET and POST)
The ItemListCreate
view handles GET (list items) and POST (create new item) requests.
Retrieve, Update, and Delete (GET, PUT, DELETE)
The ItemDetail
view handles GET (retrieve item), PUT (update item), and DELETE (delete item) requests.
7. Using Django Models and Serializers
Customizing Serializers
You can customize serializers to include additional validations or computed fields.
from rest_framework import serializers
from .models import Itemclass ItemSerializer(serializers.ModelSerializer):
name_uppercase = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ['id', 'name', 'description', 'name_uppercase']
def get_name_uppercase(self, obj):
return obj.name.upper()
Serializer Validation
You can add custom validation methods in serializers:
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ['id', 'name', 'description'] def validate_name(self, value):
if 'bad' in value.lower():
raise serializers.ValidationError("Name contains inappropriate word.")
return value
8. Implementing Authentication
Adding Token Authentication
Install the djangorestframework-simplejwt
package for JWT authentication:
pip install djangorestframework-simplejwt
Configure the authentication in myproject/settings.py
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
Update the urls.py
to include JWT endpoints:
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('myapp.urls')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
9. Error Handling and Validation
Custom Error Handling
You can create custom exception handlers. Add the following in myproject/settings.py
:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'myproject.exceptions.custom_exception_handler',
}
Create the exceptions.py
file:
from rest_framework.views import exception_handlerdef custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
response.data['status_code'] = response.status_code
return response
Model Validation
You can add validation directly in models:
from django.core.exceptions import ValidationErrorclass Item(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def clean(self):
if 'bad' in self.name.lower():
raise ValidationError("Name contains inappropriate word.")
10. Testing Your API
Writing Tests
Create tests in myapp/tests.py
:
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from .models import Itemclass ItemTests(APITestCase):
def test_create_item(self):
url = reverse('item-list-create')
data = {'name': 'Test Item', 'description': 'A test item'}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Item.objects.count(), 1)
self.assertEqual(Item.objects.get().name, 'Test Item')
def test_get_items(self):
url = reverse('item-list-create')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
Running Tests
Run the tests with the following command:
python manage.py test
11. Documentation with Swagger
Setting Up Swagger
Swagger is a tool for documenting APIs. You can use the drf-yasg
library for automatic documentation generation:
pip install drf-yasg
Add the following to your urls.py
:
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapischema_view = get_schema_view(
openapi.Info(
title="My API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="[email protected]"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('myapp.urls')),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
]
Now, navigate to http://127.0.0.1:8000/swagger/
to see the Swagger documentation.
12. Deployment
Using Gunicorn
Gunicorn is a Python WSGI HTTP Server for UNIX. It’s a pre-fork worker model, which means it forks multiple worker processes to handle requests.
Install Gunicorn:
pip install gunicorn
Run your Django app with Gunicorn:
gunicorn myproject.wsgi:application
Deploying to Heroku
Heroku is a cloud platform that lets you deploy, manage, and scale apps.
- Install the Heroku CLI.
- Create a
Procfile
with the following content:Procfileweb: gunicorn myproject.wsgi
- Create
requirements.txt
with:bashpip freeze > requirements.txt
- Deploy your app:bash
heroku create
git add .
git commit -m "Initial commit"
git push heroku master
Configuring Static Files
Configure your static files for production. Add the following in myproject/settings.py
:
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
Run the collectstatic management command:
python manage.py collectstatic
13. Conclusion
Creating a REST API with Django and Django REST framework is a powerful way to build web applications and APIs. Django provides a robust and scalable framework, while Django REST framework adds flexibility and convenience for building APIs. By following best practices and utilizing the extensive features of Django and DRF, you can create efficient, secure, and well-documented APIs.
This comprehensive guide has covered the basics of setting up a Django project, creating models and serializers, defining views, implementing authentication, error handling, testing, documentation, and deployment. With this knowledge, you are well-equipped to start building your own REST APIs with Django and Django REST framework.