Build a robust, full-featured REST API using Django REST Framework. Learn serializers, viewsets, authentication, permissions, and pagination - ideal for complex, database-driven APIs that need enterprise-grade features out of the box.
This document explains the Django REST framework example provided for data catalog management.
The example demonstrates how to:
data_catalog/
│
├── data_catalog/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
│
├── datasets/
│ ├── migrations/
│ │ └── __init__.py
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── serializers.py
│ ├── views.py
│ └── tests.py
│
├── manage.py
│
├── requirements.txt
│
└── README.md
Here's a brief explanation of each component:
data_catalog/ (outer): This is the root directory of your project.
data_catalog/ (inner): This is the main Django project directory.
settings.py: Contains all the configuration for your Django project.urls.py: The main URL declarations for your project.asgi.py and wsgi.py: Entry points for ASGI and WSGI servers.datasets/: This is your Django app directory.
migrations/: Contains database migration files.admin.py: Configuration for the Django admin interface.apps.py: Configuration for the app itself.models.py: Contains the data models (Dataset and DataPoint).serializers.py: Contains the serializer classes for your models.views.py: Contains the viewsets and logic for your API endpoints.tests.py: For writing tests for your app.manage.py: A command-line utility for interacting with your Django project.
requirements.txt: Lists all the Python packages required for your project.
README.md: A markdown file with information about your project.
This structure follows Django's conventional layout, with the addition of serializers.py for Django REST framework serializers. You might also want to add more files as your project grows, such as:
datasets/urls.py: If you want to keep URL patterns specific to the datasets app separate.datasets/filters.py: If you implement custom filtering logic.datasets/permissions.py: For custom permission classes.First, create a new Django project and app:
django-admin startproject data_catalog cd data_catalog python manage.py startapp datasets pip install djangorestframework django-filter
In datasets/models.py:
from django.db import models class Dataset(models.Model): name = models.CharField(max_length=100) description = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) file_path = models.CharField(max_length=255) file_size = models.IntegerField() # in bytes row_count = models.IntegerField() class DataPoint(models.Model): dataset = models.ForeignKey(Dataset, on_delete=models.CASCADE, related_name='datapoints') timestamp = models.DateTimeField() value = models.FloatField()
These models define the structure for datasets and individual data points.
In datasets/serializers.py:
from rest_framework import serializers from .models import Dataset, DataPoint class DataPointSerializer(serializers.ModelSerializer): class Meta: model = DataPoint fields = ['id', 'timestamp', 'value'] class DatasetSerializer(serializers.ModelSerializer): class Meta: model = Dataset fields = ['id', 'name', 'description', 'created_at', 'updated_at', 'file_path', 'file_size', 'row_count'] class DatasetDetailSerializer(DatasetSerializer): datapoints = DataPointSerializer(many=True, read_only=True) class Meta(DatasetSerializer.Meta): fields = DatasetSerializer.Meta.fields + ['datapoints']
Serializers define how the model instances are converted to JSON representations.
In datasets/views.py:
from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from .models import Dataset, DataPoint from .serializers import DatasetSerializer, DatasetDetailSerializer, DataPointSerializer from django.db.models import Avg, Max, Min from rest_framework.permissions import IsAuthenticatedOrReadOnly class DatasetViewSet(viewsets.ModelViewSet): queryset = Dataset.objects.all() serializer_class = DatasetSerializer permission_classes = [IsAuthenticatedOrReadOnly] def get_serializer_class(self): if self.action == 'retrieve': return DatasetDetailSerializer return DatasetSerializer @action(detail=True, methods=['get']) def stats(self, request, pk=None): dataset = self.get_object() stats = dataset.datapoints.aggregate( avg_value=Avg('value'), max_value=Max('value'), min_value=Min('value') ) return Response(stats) class DataPointViewSet(viewsets.ModelViewSet): queryset = DataPoint.objects.all() serializer_class = DataPointSerializer permission_classes = [IsAuthenticatedOrReadOnly] filterset_fields = ['dataset', 'timestamp']
ViewSets define the behavior of the API endpoints.
In data_catalog/urls.py:
from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter from datasets.views import DatasetViewSet, DataPointViewSet router = DefaultRouter() router.register(r'datasets', DatasetViewSet) router.register(r'datapoints', DataPointViewSet) urlpatterns = [ path('admin/', admin.site.urls), path('api/', include(router.urls)), ]
This sets up the URL routing for the API endpoints.
In data_catalog/settings.py, add:
INSTALLED_APPS = [ # ... other apps ... 'rest_framework', 'django_filters', 'datasets', ] REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10, 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], }
This configures Django REST framework settings and adds necessary apps.
Apply migrations:
python manage.py makemigrations
python manage.py migrate
Create a superuser:
python manage.py createsuperuser
Run the development server:
python manage.py runserver
Now you can access the API. Here are some ways to interact with it:
http://127.0.0.1:8000/api/curl http://127.0.0.1:8000/api/datasets/curl -X POST http://127.0.0.1:8000/api/datasets/ -H "Content-Type: application/json" -d '{"name":"Sample Dataset", "description":"A test dataset", "file_path":"/path/to/file.csv", "file_size":1024, "row_count":100}' -u username:passwordcurl http://127.0.0.1:8000/api/datasets/1/stats/This example demonstrates how Django REST framework can be used to create a robust API for data catalog management and basic data analysis.