API REST pour gérer des projets de développement collaboratifs avec système de suivi de problèmes (issues) et commentaires.
- Prérequis
- Installation
- Configuration
- Lancement
- Utilisation de l'API
- Structure du projet
- Documentation
Avant de commencer, assurez-vous d'avoir installé :
- Python 3.13 ou supérieur
- pip (gestionnaire de paquets Python)
- Git (pour cloner le projet)
- PowerShell (Windows) ou Terminal (Mac/Linux)
python --version # Doit afficher Python 3.13.x
pip --version # Doit afficher pip 24.x ou supérieur
git --version # Doit afficher git version 2.xgit clone https://github.com/votre-username/OC_SoftDesk.git
cd OC_SoftDeskWindows (PowerShell) :
python -m venv .venv
.venv\Scripts\Activate.ps1Mac/Linux :
python3 -m venv .venv
source .venv/bin/activateVous devriez voir (.venv) apparaître dans votre terminal.
pip install --upgrade pip
pip install -r requirements.txtDépendances principales :
- Django 6.0
- djangorestframework 3.16.1
- djangorestframework-simplejwt 5.3.0+
- django-cors-headers 4.9.0+
- drf-nested-routers 0.95.0+
Si le fichier requirements.txt n'existe pas :
pip install django==6.0
pip install djangorestframework==3.16.1
pip install djangorestframework-simplejwt
pip install django-cors-headers
pip install drf-nested-routers
pip freeze > requirements.txtPour la production, créez un fichier .env à la racine :
SECRET_KEY=votre-clé-secrète-django
DEBUG=False
ALLOWED_HOSTS=localhost,127.0.0.1
DATABASE_URL=sqlite:///db.sqlite3Note : Pour le développement, les valeurs par défaut dans settings.py suffisent.
Le projet utilise SQLite par défaut (aucune configuration nécessaire).
Pour PostgreSQL en production, modifiez core/settings.py :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'softdesk_db',
'USER': 'votre_user',
'PASSWORD': 'votre_password',
'HOST': 'localhost',
'PORT': '5432',
}
}python manage.py makemigrations
python manage.py migrateCela crée les tables :
users_customuser(utilisateurs)projects_project(projets)projects_contributor(contributeurs)issues_issue(problèmes)issues_comment(commentaires)
python manage.py createsuperuserSuivez les instructions :
- Username :
admin - Email :
admin@example.com - Password : (votre mot de passe)
- Age :
30 - can_be_contacted :
yes - can_data_be_shared :
yes
python manage.py loaddata fixtures/initial_data.jsonpython manage.py runserverLe serveur démarre sur http://127.0.0.1:8000/
Vous devriez voir :
Django version 6.0, using settings 'core.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Ouvrez votre navigateur : http://127.0.0.1:8000/admin/
Connectez-vous avec le superutilisateur créé précédemment.
L'API REST est accessible sur : http://127.0.0.1:8000/api/
Endpoint : POST /api/auth/register/
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/auth/register/" `
-Method Post `
-Body (@{
username="alice"
password="motdepasse123"
email="alice@example.com"
age=25
can_be_contacted=$true
can_data_be_shared=$true
} | ConvertTo-Json) `
-ContentType "application/json"Alternative avec cURL :
curl -X POST http://127.0.0.1:8000/api/auth/register/ \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"motdepasse123","email":"alice@example.com","age":25}'Endpoint : POST /api/token/
$response = Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/token/" `
-Method Post `
-Body (@{username="alice"; password="motdepasse123"} | ConvertTo-Json) `
-ContentType "application/json"
$token = $response.access
Write-Host "Token: $token"Réponse :
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Exemple : Créer un projet
$headers = @{Authorization="Bearer $token"}
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/projects/" `
-Method Post `
-Headers $headers `
-Body (@{
name="Mon Projet API"
description="Description du projet"
type="backend"
} | ConvertTo-Json) `
-ContentType "application/json"POST /api/auth/register/ # Inscription
POST /api/token/ # Login (obtenir token)
POST /api/token/refresh/ # Rafraîchir token
GET /api/auth/profile/ # Voir son profil
DELETE /api/auth/profile/ # Supprimer son compte (RGPD)
GET /api/projects/ # Liste des projets (paginé)
POST /api/projects/ # Créer un projet
GET /api/projects/{id}/ # Détail d'un projet
PUT /api/projects/{id}/ # Modifier un projet (auteur)
DELETE /api/projects/{id}/ # Supprimer un projet (auteur)
GET /api/projects/{id}/contributors/ # Liste des contributeurs
POST /api/projects/{id}/contributors/ # Ajouter un contributeur (auteur)
DELETE /api/projects/{pid}/contributors/{cid}/ # Retirer un contributeur
GET /api/projects/{id}/issues/ # Liste des issues
POST /api/projects/{id}/issues/ # Créer une issue
GET /api/projects/{pid}/issues/{iid}/ # Détail d'une issue
PUT /api/projects/{pid}/issues/{iid}/ # Modifier (auteur issue)
DELETE /api/projects/{pid}/issues/{iid}/ # Supprimer (auteur issue)
GET /api/projects/{p}/issues/{i}/comments/ # Liste
POST /api/projects/{p}/issues/{i}/comments/ # Créer
GET /api/projects/{p}/issues/{i}/comments/{c}/ # Détail
PUT /api/projects/{p}/issues/{i}/comments/{c}/ # Modifier (auteur)
DELETE /api/projects/{p}/issues/{i}/comments/{c}/ # Supprimer (auteur)
Toutes les listes sont paginées (10 éléments par page) :
# Page 1
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/projects/" -Headers $headers
# Page 2
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/projects/?page=2" -Headers $headersRéponse paginée :
{
"count": 42,
"next": "http://127.0.0.1:8000/api/projects/?page=2",
"previous": null,
"results": [ /* 10 projets */ ]
}OC_SoftDesk/
│
├── core/ # Configuration Django
│ ├── __init__.py
│ ├── settings.py # Configuration principale
│ ├── urls.py # URLs racine
│ ├── wsgi.py
│ └── asgi.py
│
├── users/ # App utilisateurs
│ ├── models.py # CustomUser (RGPD)
│ ├── views.py # Register, Profile, Delete
│ ├── serializers.py # UserSerializer
│ ├── urls.py
│ └── permissions.py # IsSelfUser
│
├── projects/ # App projets
│ ├── models.py # Project, Contributor
│ ├── views.py # ProjectViewSet, ContributorViewSet
│ ├── serializers.py # ProjectListSerializer, ProjectDetailSerializer
│ ├── permissions.py # IsProjectAuthor, IsProjectContributor...
│ └── urls.py
│
├── issues/ # App issues & commentaires
│ ├── models.py # Issue, Comment
│ ├── views.py # IssueViewSet, CommentViewSet
│ ├── serializers.py # IssueListSerializer, IssueDetailSerializer
│ ├── permissions.py # IsIssueAuthorOrReadOnly...
│ └── urls.py
│
├── db.sqlite3 # Base de données (dev)
├── manage.py # Script de gestion Django
├── pyproject.toml # Configuration Poetry
├── requirements.txt # Dépendances pip
│
└── Documentation/
├── README.md # Ce fichier
├── COMPTE_RENDU.md # Explication complète
├── PERMISSIONS.md # Système de permissions
├── OPTIMISATION.md # Optimisations performance
├── REFACTORING.md # Améliorations possibles
└── CHECKLIST.md # Validation exigences
python manage.py testpip install coverage
coverage run --source='.' manage.py test
coverage report
coverage html # Génère un rapport HTML dans htmlcov/- Importer la collection Postman (si disponible)
- Configurer la variable d'environnement
base_url=http://127.0.0.1:8000 - Configurer la variable
tokenaprès le login - Exécuter les requêtes
✅ Consentement explicite : Champs can_be_contacted et can_data_be_shared
✅ Protection mineurs : can_data_be_shared forcé à False si âge < 15 ans
✅ Droit à l'oubli : DELETE /api/auth/profile/ supprime toutes les données (CASCADE)
✅ Confidentialité : Les utilisateurs ne voient que leurs projets
✅ Suppression réelle : Pas de soft-delete
- Access token : Valide 60 minutes
- Refresh token : Valide 10 jours
- Header requis :
Authorization: Bearer <token>
- Projet : Seul l'auteur peut modifier/supprimer
- Contributeur : Seul l'auteur du projet peut ajouter/retirer
- Issue : Seul l'auteur de l'issue peut modifier/supprimer
- Commentaire : Seul l'auteur du commentaire peut modifier/supprimer
Projet éducatif - OpenClassrooms 2026
Noam
Formation : Développeur Python - OpenClassrooms
Date : Janvier 2026
- Backend : Django 6.0, Django REST Framework 3.16
- Authentification : djangorestframework-simplejwt (JWT)
- Base de données : SQLite (dev) / PostgreSQL (prod)
- Routing : drf-nested-routers
- CORS : django-cors-headers
- Python : 3.13
Bon développement ! 🚀