Django : le framework web Python expliqué

Développement web • Python • Radio amateur

Django : le framework web Python expliqué simplement

De la théorie à la pratique, en passant par la radio amateur — et une API concrète disponible sur django.jerko.fr.

Mais c’est quoi, Django ?

Django est un framework web écrit en Python, publié en 2005 et aujourd’hui maintenu par la Django Software Foundation. L’idée de départ était simple : permettre à des développeurs de journaux en ligne de produire des applications web complexes en un temps minimal, sans réinventer la roue à chaque projet.

Sa philosophie tient en un slogan officiel : « The web framework for perfectionists with deadlines ». En clair : un outil complet, opiniated (il a ses propres conventions) et qui embarque tout ce dont vous avez besoin dès l’installation.

Un framework, c’est quoi exactement ? Imaginez que vous construisez une maison. Vous pourriez façonner chaque brique vous-même, concevoir votre propre plomberie, inventer vos propres techniques de maçonnerie. Ou bien vous pouvez utiliser des matériaux standard, des plans éprouvés, et vous concentrer sur ce qui rend votre maison unique. Un framework web, c’est pareil : il fournit la structure, les outils et les conventions pour que vous n’ayez plus qu’à construire ce qui vous appartient.

L’architecture MTV : Model, Template, View

Django s’organise autour d’un patron d’architecture appelé MTV (Model – Template – View), cousin du MVC que vous connaissez peut-être. Voici comment ces trois briques s’articulent :

Composant Rôle Analogie
Model Définit la structure des données et dialogue avec la base de données Le carnet de logs du radioamateur
View Contient la logique applicative : reçoit une requête, interroge les modèles, renvoie une réponse Le TRX qui traite le signal
Template Génère le HTML final affiché à l’utilisateur L’écran du waterfall : la représentation visuelle

Avantages et inconvénients — le bilan honnête

Ce qui plaît

  • + Batteries included : ORM, auth, admin, formulaires, sécurité CSRF — tout est intégré
  • + Django REST Framework : créer une API JSON devient trivial
  • + Interface d’administration auto-générée, prête à l’emploi
  • + Sécurité : protection XSS, CSRF, injection SQL par défaut
  • + Scalabilité : Instagram, Pinterest et Disqus tournent sur Django
  • + Communauté et documentation exemplaire

Ce qui grince

  • Courbe d’apprentissage : la magie des conventions peut être déstabilisante au début
  • Monolithique : moins agile que Flask ou FastAPI pour un micro-service minimaliste
  • Synchrone par nature : l’async existe depuis Django 3.1 mais reste moins mature qu’avec FastAPI
  • ORM parfois rigide pour des requêtes SQL très complexes ou non-standard
  • Déploiement : requiert Python + WSGI/ASGI + serveur (Gunicorn, Nginx), moins clé-en-main qu’un hébergement mutualisé PHP

Django dans le monde de la radio amateur

A priori, un framework web Python et la radio amateur semblent éloignés. Mais à y réfléchir, notre activité produit des données en abondance : logs de trafic, spots DX, trames APRS, relevés WSPR, informations de porteurs… autant de sources qui se prêtent à une mise en valeur sur le web — et Django est parfaitement outillé pour ça.

Voici quelques cas d’usage concrets pour les radioamateurs :

Logbook en ligne

Stocker, rechercher et afficher vos QSO avec filtres par bande, mode ou DXCC. L’ORM Django rend les requêtes complexes lisibles et maintenables.

DX Cluster Web

Exposer les spots d’un cluster DXSpider via une API REST, consommable par n’importe quelle interface web ou application mobile.

Statistiques WSPR / FT8

Ingérer les données de propagation (wsprnet, PSKReporter), les agréger et les restituer sous forme de tableaux ou de cartes interactives.

Gestion d’association

Adhérents, cotisations, résultats de concours, partiels de diplômes — Django propose un back-office prêt à l’emploi sans une ligne de code d’interface admin.

Carte des relais / balises

Modéliser les relais (fréquence, ton CTCSS, locator, statut) et les exposer via une API GeoJSON consommée par Leaflet.js côté navigateur.

Examen radioamateur

Banque de questions, tirage aléatoire, correction et score — une application d’entraînement complète en quelques dizaines de lignes Python. Exemple concret : django.jerko.fr/quiz/

Django vs PHP pour un radioamateur ? Si vous connaissez déjà PHP/WordPress, la transition demande un investissement initial. Mais dès que vous devez traiter des données structurées en volume — logs ADIF, trames JSON d’un SDR, exports WSPR — Python et Django s’avèrent nettement plus confortables : la syntaxe est plus lisible, les bibliothèques scientifiques (NumPy, Pandas) sont disponibles, et l’ORM évite les jointures SQL manuelles.

L’interactivité via les API REST

L’un des usages les plus puissants de Django aujourd’hui n’est plus de générer des pages HTML côté serveur, mais d’exposer des API REST — des points d’entrée web qui renvoient du JSON. N’importe quel client peut alors les interroger : un navigateur, une application mobile, un script Python, un widget WordPress…

Le module Django REST Framework (DRF) est le standard de fait pour construire ces API. Il prend en charge la sérialisation des données, l’authentification, les permissions, la pagination et même une interface de navigation interactive (la Browsable API).

Exemple : requête curl sur l’API de django.jerko.fr

# Récupérer les articles du blog via l'API REST
curl -s https://django.jerko.fr/api/articles/ | python3 -m json.tool

# Réponse JSON réelle (extrait)
{
  "count": 6,
  "next": null,
  "results": [
    {
      "id": 1,
      "titre": "Circuits LC — Résonance en Radioamateurisme",
      "slug": "circuit-lc",
      "categorie": "radio",
      "date": "2026-04-11",
      "auteur": "admin"
    },
    {
      "id": 2,
      "titre": "WSPR — Weak Signal Propagation Reporter",
      "slug": "wspr-weak-signal-propagation-reporter",
      "categorie": "radio",
      "date": "2026-04-11",
      "auteur": "admin"
    },
    {
      "id": 3,
      "titre": "APRS — Automatic Packet Reporting System",
      "slug": "aprs-automatic-packet-reporting-system",
      "categorie": "radio",
      "date": "2026-04-11",
      "auteur": "admin"
    }
  ]
}

Consommer cette API depuis JavaScript (fetch)

// Afficher les articles radio depuis l'API dans une page WordPress
fetch('https://django.jerko.fr/api/articles/?categorie=radio')
  .then(r => r.json())
  .then(data => {
    console.log(`${data.count} articles dans la catégorie radio`);
    data.results.forEach(article => {
      console.log(article.titre, article.date);
    });
  });

Projet concret : un DX Cluster web avec Django

Le DX Cluster est un outil incontournable pour le radioamateur qui chasse les stations rares : il agrège en temps réel les spots émis par des opérateurs du monde entier, signalant qu’une station est active sur une fréquence donnée. Traditionnellement accessible via telnet, le DX Cluster se prête parfaitement à une mise en valeur web grâce à Django. Le déploiement DXSpider est disponible ici : f4hxn.fr/dx-spider/.

L’architecture retenue repose sur deux composants qui collaborent via une API REST :

cluster.jerko.fr

Script Python

Se connecte à un nœud DXSpider parent, ingère les spots en temps réel et les stocke en base de données


/api/spots/

Django REST API

DRF + Nginx

Expose les spots en JSON, consommables par WordPress, une appli mobile ou n’importe quel client web

Le modèle Django d’un spot DX

# dxcluster/models.py
from django.db import models

class Spot(models.Model):
    dx_call    = models.CharField(max_length=20)   # indicatif DX spotter
    freq       = models.FloatField()               # fréquence en kHz
    dx_station = models.CharField(max_length=20)   # station spottée
    comment    = models.CharField(max_length=128, blank=True)
    timestamp  = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-timestamp']   # les plus récents en premier

    def __str__(self):
        return f"{self.dx_call} — {self.dx_station} — {self.freq} kHz"

Requête sur l’API des spots

# Les 10 derniers spots
curl -s https://cluster.jerko.fr/api/spots/?limit=10 | python3 -m json.tool

{
  "count": 4821,
  "results": [
    {
      "dx_call":    "F4HXN",
      "freq":       14025.0,
      "dx_station": "TM5REF",
      "comment":    "59 CW TNX",
      "timestamp":  "2026-05-19T08:42:11Z"
    }
  ]
}

Afficher les spots en direct dans WordPress

<!-- Bloc HTML Gutenberg -->
<div id="dx-spots" style="font-family:DM Sans,sans-serif;"></div>

<script>
(function() {
  fetch('https://cluster.jerko.fr/api/spots/?limit=10')
    .then(r => r.json())
    .then(data => {
      document.getElementById('dx-spots').innerHTML =
        '<table><tr><th>Spotter</th><th>DX</th><th>Fréq. kHz</th><th>Info</th></tr>' +
        data.results.map(s =>
          `<tr><td>${s.dx_call}</td><td><b>${s.dx_station}</b></td>
               <td>${s.freq}</td><td>${s.comment}</td></tr>`
        ).join('') + '</table>';
    });
})();
</script>

Ce widget peut s’enrichir : filtrage par bande, rafraîchissement automatique toutes les 30 secondes avec setInterval(), mise en évidence des nouvelles entités DXCC… Le tout sans modifier WordPress — uniquement en jouant sur l’API Django et quelques lignes de JavaScript.

Mise en pratique : django.jerko.fr

L’instance disponible à l’adresse https://django.jerko.fr illustre concrètement ce que l’on vient de décrire. Elle tourne sur un serveur Gunicorn derrière un reverse-proxy Nginx, déployée dans une VM Proxmox. Voici comment tout ça s’articule.

La pile technique

Couche Outil Rôle
ApplicationDjango 4.x + DRFLogique métier, ORM, API REST
Serveur WSGIGunicornFait le pont entre Nginx et Django
Reverse proxyNginxSSL/TLS, fichiers statiques, routage
Base de donnéesSQLite / PostgreSQLPersistance des données
InfrastructureProxmox VM UbuntuVirtualisation, isolation, snapshots

Structure du projet Django (arborescence simplifiée)

mon-api/
├── manage.py          # CLI Django (migrations, runserver…)
├── mon_api/            # Configuration principale
│   ├── settings.py    # BDD, apps installées, debug, CORS…
│   ├── urls.py        # Routage global des URLs
│   └── wsgi.py        # Point d'entrée Gunicorn
└── logbook/            # Exemple d'application Django
    ├── models.py      # Définition de la table QSO
    ├── serializers.py # Conversion objet Python ↔ JSON
    ├── views.py       # Logique des endpoints API
    └── urls.py        # Routes locales à cette app

Un modèle de QSO en 10 lignes

# logbook/models.py
from django.db import models

class QSO(models.Model):
    callsign  = models.CharField(max_length=20)
    band      = models.CharField(max_length=10)   # ex: "40m"
    mode      = models.CharField(max_length=10)   # FT8, SSB, CW…
    locator   = models.CharField(max_length=8, blank=True)
    rst_sent  = models.IntegerField(default=59)
    rst_rcvd  = models.IntegerField(default=59)
    date_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.callsign} – {self.band} – {self.mode}"

Après python manage.py makemigrations && python manage.py migrate, Django crée automatiquement la table SQL correspondante. Aucune requête DDL à écrire à la main.

Intégrer l’API Django dans WordPress

L’API REST Django et WordPress coexistent très bien : l’un gère les données métier, l’autre gère la présentation éditoriale. Le lien entre les deux se fait côté navigateur via JavaScript — aucune modification WordPress côté serveur n’est nécessaire.

Exemple : widget dans un article WordPress (bloc HTML)

<!-- À coller dans un bloc HTML Gutenberg -->
<div id="dx-widget" style="font-family:DM Sans,sans-serif;padding:1rem;"></div>

<script>
(function() {
  const API = 'https://django.jerko.fr/api/spots/?limit=10';
  fetch(API)
    .then(r => r.json())
    .then(data => {
      const el = document.getElementById('dx-widget');
      el.innerHTML = data.results.map(s =>
        `<p><strong>${s.dx}</strong> — ${s.freq} kHz — ${s.spotter}</p>`
      ).join('');
    });
})();
</script>

Astuce CORS — Pour que le navigateur accepte la requête vers un domaine différent (django.jerko.fr depuis f4hxn.fr), il faut autoriser les origines dans Django :

# settings.py
INSTALLED_APPS += ['corsheaders']
MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', ...autres...]
CORS_ALLOWED_ORIGINS = ['https://f4hxn.fr', 'https://frimousse.net']

Déploiement pas à pas sur Proxmox / Ubuntu

La procédure suivante correspond à la mise en production effective de django.jerko.fr.

1

Créer la VM et installer Python

sudo apt install python3-pip python3-venv -y
2

Créer l’environnement virtuel et installer Django

python3 -m venv /opt/mon-api/venv
source /opt/mon-api/venv/bin/activate
pip install django djangorestframework gunicorn django-cors-headers
3

Créer le projet et appliquer les migrations

django-admin startproject mon_api /opt/mon-api
cd /opt/mon-api
python manage.py migrate
python manage.py createsuperuser
4

Configurer Gunicorn comme service systemd

# /etc/systemd/system/gunicorn-monapi.service
[Service]
WorkingDirectory=/opt/mon-api
ExecStart=/opt/mon-api/venv/bin/gunicorn \
          --workers 3 --bind unix:/run/gunicorn-monapi.sock \
          mon_api.wsgi:application
5

Configurer le vhost Nginx

server {
    listen 443 ssl;
    server_name django.jerko.fr;

    location / {
        proxy_pass http://unix:/run/gunicorn-monapi.sock;
        proxy_set_header Host $host;
    }

    location /static/ {
        alias /opt/mon-api/staticfiles/;
    }
}

Ce qu’il faut retenir

Django n’est pas un outil qui remplace WordPress — ce sont deux mondes différents. WordPress excelle pour la gestion de contenu éditorial, le blog, les pages statiques. Django excelle quand vous avez des données métier complexes à modéliser, exposer et manipuler via une API.

Pour un radioamateur actif — qui génère des logs, des spots, des trames WSPR, des données ADS-B — Django ouvre des perspectives intéressantes : construire son propre back-end de données, l’exposer via une API REST propre, et l’intégrer dans n’importe quelle interface, y compris ses pages WordPress existantes, avec quelques lignes de JavaScript.

Le projet django.jerko.fr en est la démonstration en conditions réelles : une API Python déployée sur infrastructure Proxmox, accessible depuis n’importe quel client, prête à être enrichie selon les besoins.

Ressources pour aller plus loin

Documentation officielle : docs.djangoproject.com • DRF : django-rest-framework.org • CORS : pypi.org/project/django-cors-headers

Un grand merci à Yoann F4JTV qui m’a fait découvrir Django et m’a donné l’envie de creuser ce framework.

C’est souvent par un échange entre radioamateurs passionnés qu’on franchit le pas vers de nouveaux horizons techniques — et Django en est la preuve.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *