Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🐍 Django REST Framework – Guide Approfondi

Guide IDEO‑Lab complet pour maĂźtriser la crĂ©ation d'APIs avec DRF.

1

Introduction & Concepts

Le "Pourquoi ?" : API, REST, Serializer, View, Router.

REST Concepts API
2

Installation & Configuration

settings.py, variables .env, configuration globale.

settings.py .env DEFAULT_
3

Serializers (Le CƓur)

ModelSerializer, validation, relations (FK, M2M).

Serializer ModelSerializer Validation
4

Vues & ViewSets

APIView, Generic Views, ModelViewSet, @action.

APIView ViewSet @action
5

Auth & Permissions

Token, Session, OAuth2, permissions personnalisées.

TokenAuthentication Permissions
6

Routage & URLs

SimpleRouter, DefaultRouter, routing imbriqué.

Routers urls.py
7

Pagination & Filtres

PageNumberPagination, django-filter, SearchFilter.

Pagination Filtering
8

Cas d'usage : Mini-Blog

Exemple complet de CRUD (Articles + Auteurs).

CRUD Exemple
1. Introduction & Concepts Clés
Qu'est-ce que Django REST Framework ?

Django REST Framework (DRF) est un **toolkit puissant et flexible** pour construire des API Web avec Django. Il ne remplace pas Django, il s'appuie dessus pour faciliter la création de points d'accÚs (endpoints) qui retournent des données structurées (JSON, XML) au lieu de HTML.

Quel problÚme cela résout-il ?

Django seul est conçu pour le pattern MTV (Model-Template-View) : il récupÚre des données de la BDD et les injecte dans un template HTML. C'est parfait pour les sites web traditionnels.

Aujourd'hui, vous avez besoin de plus :

  • Une application mobile (iOS/Android) doit rĂ©cupĂ©rer les mĂȘmes donnĂ©es.
  • Un frontend moderne (React, Vue, Angular) doit interagir avec votre backend.
  • Un partenaire externe veut se connecter Ă  votre service.

Ces clients ne veulent pas de HTML. Ils veulent des **données brutes** (ex: JSON). DRF est la surcouche qui transforme Django en un puissant serveur d'API RESTful.

Les 4 Piliers de DRF
1. Serializers (Sérialiseurs)

C'est le cƓur de DRF. Ils font la **traduction** dans les deux sens :

  • Objet Python/ModĂšle Django -> JSON : Pour l'envoyer au client (SĂ©rialisation).
  • JSON -> Objet Python/ModĂšle Django : Pour valider et enregistrer les donnĂ©es reçues du client (DĂ©sĂ©rialisation).
2. Vues (Views / ViewSets)

C'est la **logique mĂ©tier**. La vue reçoit une requĂȘte (ex: GET /api/articles/1), utilise le Serializer pour rĂ©cupĂ©rer et formater l'article, et le renvoie en JSON.

DRF fournit des vues génériques (APIView, ModelViewSet) qui gÚrent 90% du travail d'un CRUD (Create, Read, Update, Delete) pour vous.

3. Routers (Routeurs)

Le routeur génÚre **automatiquement** les URLs pour vos ViewSets. Vous n'avez pas besoin de définir manuellement les URLs pour `list`, `detail`, `create`, `update`, etc. Le routeur s'en charge.

4. Authentification & Permissions

DRF étend le systÚme d'authentification de Django pour les APIs. Il gÚre l'authentification par Token, par Session, OAuth, etc. Les **Permissions** définissent qui a le droit de faire quoi (ex: `IsAuthenticated`, `IsAdminUser`, ou des permissions personnalisées).

Quand utiliser DRF ?

Utilisez DRF si :

  • Votre backend doit servir de donnĂ©es Ă  un **frontend sĂ©parĂ©** (React, Vue, Angular).
  • Vous construisez une **application mobile** qui a besoin d'un backend.
  • Vous exposez une **API publique** ou privĂ©e pour des partenaires.
  • Vous voulez standardiser la communication entre microservices.
Quand est-ce *overkill* ?

N'utilisez pas DRF (ou une API) si :

  • Votre projet est un **site web 100% traditionnel** (ex: blog, site vitrine) oĂč Django rend tous les templates HTML.
  • Vous avez juste besoin de 1 ou 2 "endpoints" simples. Une vue Django classique retournant un JsonResponse peut suffire.
Alternatives Populaires
1. Django-Ninja
  • Approche : "API-first", trĂšs moderne, s'inspire de FastAPI.
  • Avantage : Utilise la **validation de type Pydantic** (trĂšs puissant) et gĂ©nĂšre automatiquement une documentation OpenAPI (Swagger/Redoc) de haute qualitĂ©.
  • InconvĂ©nient : Moins mature que DRF, Ă©cosystĂšme plus petit.
2. FastAPI (Framework Python, pas Django)
  • Approche : Un micro-framework Python dĂ©diĂ© aux APIs, basĂ© sur Starlette et Pydantic.
  • Avantage : ExtrĂȘmement rapide (performance asynchrone), validation de type intĂ©grĂ©e, documentation auto.
  • InconvĂ©nient : N'inclut pas l'Ă©cosystĂšme Django (pas d'Admin, pas d'ORM Django, pas de systĂšme d'authentification complet par dĂ©faut).
DRF vs. Ninja : Lequel choisir ?

En 2025, le choix se résume souvent à :

  • Prenez DRF : Si vous avez un **projet Django existant** Ă  transformer en API, ou si vous tenez Ă  l'Ă©cosystĂšme d'addons de DRF (ex: `drf-spectacular`, `djoser`). C'est le choix le plus robuste et testĂ©.
  • Prenez Django-Ninja : Si vous dĂ©marrez un **nouveau projet Django** et que votre prioritĂ© absolue est la **performance** et la **documentation OpenAPI** automatique.
2. Installation & Configuration
Installation (Python venv)
# S'assurer que le venv est activé
# source venv/bin/activate

pip install djangorestframework
pip install markdown       # Requis pour l'API "Browsable"
pip install django-filter  # Requis pour le filtrage
Ajout Ă  settings.py

Ajoutez 'rest_framework' à vos applications installées.

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    # Apps tierces
    'rest_framework',
    'rest_framework.authtoken', # Pour l'authentification par Token
    'django_filters',           # Pour le filtrage
    
    # Vos apps
    'core',
    'accounts',
]
Configuration Globale de DRF

Toutes les configurations globales de DRF se font dans un dictionnaire REST_FRAMEWORK dans votre settings.py.

Voici une configuration de **départ solide** et sécurisée pour la plupart des projets :

# settings.py

REST_FRAMEWORK = {
    
    # --- AUTHENTIFICATION ---
    # Par défaut : Token (pour scripts/apps) et Session (pour l'API browsable)
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication', 
    ],

    # --- PERMISSIONS ---
    # Politique par défaut : Tout est fermé, sauf si authentifié.
    # (Alternative : IsAuthenticatedOrReadOnly pour autoriser lecture)
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],

    # --- PAGINATION ---
    # Active la pagination globale pour toutes les listes
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 25, # Nombre d'items par page

    # --- FILTRAGE ---
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    ],
    
    # --- SCHÉMA & DOCS ---
    # Utilise drf-spectacular (à installer) pour générer OpenAPI 3.0
    # 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
Sécurité : Ne jamais coder en dur !

Votre configuration REST_FRAMEWORK ne doit pas contenir de clés secrÚtes. Cependant, d'autres paramÚtres (comme ceux pour Sentry ou les BDD) le feront.

Utilisez toujours des variables d'environnement (via python-dotenv).

Exemple avec .env
# .env (Ă  la racine du projet, dans .gitignore)
DJANGO_SECRET_KEY="votre-secret-key-ici"
DJANGO_DEBUG=True
SENTRY_DSN="https://..."
Utilisation dans settings.py
# settings.py
from dotenv import load_dotenv
import os
load_dotenv() # Charge le fichier .env

SECRET_KEY = os.getenv("DJANGO_SECRET_KEY")
DEBUG = os.getenv("DJANGO_DEBUG", "False") == "True"

# Exemple de configuration de Sentry (addon populaire)
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

SENTRY_DSN = os.getenv("SENTRY_DSN")
if SENTRY_DSN:
    sentry_sdk.init(
        dsn=SENTRY_DSN,
        integrations=[DjangoIntegration()],
        traces_sample_rate=0.2,
    )
Ajout des URLs de base

Pour utiliser l'API "Browsable" et l'authentification par Token, vous devez ajouter quelques URLs au fichier urls.py principal de votre projet.

# ideolab_site/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken import views as authtoken_views

urlpatterns = [
    path('admin/', admin.site.urls),
    
    # --- URLs de base DRF ---
    
    # 1. URLs de l'API (ex: /api/v1/)
    # On délÚgue toutes nos URLs d'API à un fichier séparé
    path('api/v1/', include('core.api_urls')), # 'core' est un exemple d'app

    # 2. API "Browsable" (Login / Logout)
    # Requis pour pouvoir se connecter/déconnecter de l'interface web
    path('api-auth/', include('rest_framework.urls')),
    
    # 3. Authentification par Token
    # Permet Ă  un client de faire un POST avec 'username' et 'password'
    # pour obtenir un Token en retour.
    path('api-token-auth/', authtoken_views.obtain_auth_token),

    # ... vos autres urls ...
]
3. Serializers (Le CƓur)
ModelSerializer

[...Contenu détaillé sur le ModelSerializer...]

[...Exemple de code pour un ArticleSerializer...]
class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ('id', 'title', 'content', 'author', 'created_at')
        read_only_fields = ('author',)
Validation

[...Contenu détaillé sur la validation de champ (validate_field) et la validation d'objet (validate)...]

[...Exemple de code pour valider un titre...]
def validate_title(self, value):
    if "Django" not in value:
        raise serializers.ValidationError("Le titre doit contenir 'Django'")
    return value
Relations (Foreign Key, ManyToMany)

[...Contenu détaillé sur PrimaryKeyRelatedField, StringRelatedField, Nested Serializers et SlugRelatedField...]

Champs Avancés

[...Contenu détaillé sur SerializerMethodField, ReadOnlyField, et comment gérer l'écriture (write-only)...]

PiĂšges & Bonnes Pratiques

[...Contenu détaillé sur le problÚme N+1 (select_related, prefetch_related) et la gestion des champs "write-only" (ex: mot de passe)...]

4. Vues & ViewSets
APIView

[...Contenu détaillé sur APIView, quand l'utiliser (logique complexe, endpoints non-CRUD)...]

Vues Génériques (ListCreateAPIView, RetrieveUpdateDestroyAPIView)

[...Contenu détaillé sur les vues génériques, un bon compromis entre APIView et ViewSets...]

ModelViewSet

[...Contenu détaillé sur ModelViewSet, le moyen le plus rapide de créer un CRUD complet. Définition de queryset et serializer_class...]

[...Exemple de code ArticleViewSet...]
class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]
Actions Personnalisées (@action)

[...Contenu détaillé sur l'ajout d'endpoints personnalisés à un ViewSet (ex: /api/articles/1/publish/)...]

[...Exemple de code pour @action(detail=True)...]
5. Authentification & Permissions
Token vs Session

[...Contenu dĂ©taillĂ© sur le choix du backend. TokenAuthentication pour les clients lourds/mobiles, SessionAuthentication pour les frontends web (SPA) sur le mĂȘme domaine (sĂ©curitĂ© CSRF)...]

Permissions Incluses

[...Contenu détaillé sur IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly, AllowAny...]

Permissions Personnalisées

[...Contenu détaillé sur la création d'une permission personnalisée en héritant de BasePermission et en surchargeant has_object_permission()...]

[...Exemple de permission IsAuthorOrReadOnly...]
JWT & OAuth2

[...Contenu détaillé sur les alternatives au Token simple. Présentation de Simple-JWT et Django-OAuth-Toolkit...]

6. Routage & URLs
SimpleRouter vs DefaultRouter

[...Contenu détaillé. DefaultRouter inclut l'endpoint racine (l'API Browsable), SimpleRouter ne le fait pas. 99% du temps, utilisez DefaultRouter...]

Configuration

[...Contenu détaillé sur la création d'un fichier `api_urls.py` dans une app, et comment l'inclure dans le `urls.py` principal...]

[...Exemple de code pour un router.register()...]
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register(r'articles', views.ArticleViewSet, basename='article')
router.register(r'users', views.UserViewSet, basename='user')

urlpatterns = router.urls
Routage Imbriqué

[...Contenu détaillé sur la création d'URLs imbriquées (ex: /api/articles/1/comments/2/) avec `drf-nested-routers`...]

7. Pagination, Filtres & Recherche
Pagination

[...Contenu détaillé sur PageNumberPagination (globale vs. par vue) et CursorPagination (pour les feeds infinis)...]

Filtrage (django-filter)

[...Contenu détaillé sur l'utilisation de `django-filter` pour permettre des filtres sur les query params (ex: /api/articles/?author=1&published=true)...]

8. Cas d'usage : Mini-Blog (CRUD Complet)
models.py

[...ModĂšle Article (avec FK vers User) et ModĂšle Commentaire (avec FK vers Article et User)...]

serializers.py

[...ArticleSerializer (avec `author` en `ReadOnlyField`) et CommentSerializer...]

views.py

[...ArticleViewSet (avec permission `IsAuthorOrReadOnly`) et CommentViewSet (avec permission `IsOwnerOrReadOnly`). Surcharge de `perform_create` pour lier l'auteur...]

api_urls.py

[...Utilisation de `drf-nested-routers` pour avoir /api/articles/<id>/comments/...]