DjangoPythonFormationArchitecture MVTIntermédiaire

Maîtriser Django : comprendre l'architecture MVT, les fichiers clés et l'organisation d'un projet

Vous avez initialisé votre premier projet Django : bravo ! Mais que font réellement models.py, views.py, urls.py et les templates ? Quand faut-il créer de nouveaux fichiers ou dossiers ? Dans cette formation, nous allons démystifier l'architecture Django de fond en comble, avec des exemples concrets tirés d'un projet de blog.
Sommaire
  1. Le patron MVT : le cœur de Django
  2. Décryptage de chaque fichier
  3. Le cycle complet d'une requête
  4. models.py : définir vos données
  5. urls.py : router les requêtes
  6. views.py : la logique applicative
  7. Les templates : l'affichage HTML
  8. admin.py : l'interface d'administration
  9. forms.py : gérer les formulaires
  10. Quand créer de nouveaux fichiers et dossiers ?
  11. Organisation recommandée pour un projet réel

1. Le patron MVT : le cœur de Django

Django repose sur le patron d'architecture MVT : Model, View, Template. C'est une variante du célèbre MVC (Model-View-Controller), adaptée au développement web. Chaque composant a une responsabilité précise et unique :

Model
Définit la structure des données et dialogue avec la base de données via l'ORM Django. Correspond au fichier models.py.
View
Contient la logique applicative : récupère les données, applique des règles métier, prépare le contexte. Correspond à views.py.
Template
Gère l'affichage HTML. Reçoit des variables du View et les insère dans des fichiers .html stockés dans le dossier templates/.

Le fichier urls.py agit comme un aiguilleur : il intercepte chaque URL entrante et la dirige vers la bonne View.

2. Décryptage de chaque fichier

Voici l'arborescence d'une application Django typique (ici une app blog) et le rôle précis de chaque fichier :

blog/
  ├── migrations/ ← historique des modif. BDD (auto-généré)
  │   └── 0001_initial.py
  ├── templates/ ← fichiers HTML
  │   └── blog/
  │       ├── liste.html
  │       └── detail.html
  ├── __init__.py ← déclare le dossier comme module Python
  ├── admin.py ← enregistre les modèles dans l'interface admin
  ├── apps.py ← configuration de l'app
  ├── forms.py ← formulaires Django (à créer si besoin)
  ├── models.py ← structure des données
  ├── urls.py ← routes propres à l'app (à créer)
  └── views.py ← logique et réponses
💡 Note importante : le fichier urls.py et le dossier templates/ ne sont pas créés automatiquement dans une app. Vous devez les créer manuellement.

3. Le cycle complet d'une requête HTTP

Comprendre l'ordre dans lequel Django traite une requête est fondamental. Voici ce qui se passe lorsqu'un utilisateur visite une URL de votre site :

Navigateur
urls.py (projet)
urls.py (app)
views.py
models.py
template .html
Réponse HTTP

Chaque flèche représente une étape. Django commence toujours par le routage des URLs, puis délègue à la View qui ira chercher des données dans les Models, avant de rendre un Template et de retourner la réponse au navigateur.

4. models.py : définir la structure de vos données

Le fichier models.py est l'endroit où vous décrivez vos entités de données. Chaque classe Python héritant de models.Model correspond à une table dans votre base de données. Pas besoin d'écrire du SQL : Django's ORM s'en charge.

Exemple : modèle Article pour un blog

from django.db import models
from django.utils import timezone

class Article(models.Model):
    titre = models.CharField(max_length=200)
    contenu = models.TextField()
    date_publication = models.DateTimeField(default=timezone.now)
    publie = models.BooleanField(default=False)

    class Meta:
        ordering = ['-date_publication']  # du plus récent au plus ancien

    def __str__(self):
        return self.titre

Les types de champs les plus utilisés

CharField
Texte court. Toujours accompagné de max_length. Exemple : titre, nom.
TextField
Texte long sans limite. Idéal pour des contenus, descriptions, corps d'article.
IntegerField
Nombre entier. Pour des quantités, scores, âges.
DateTimeField
Date et heure. Avec auto_now_add=True pour enregistrer la date de création.
BooleanField
Vrai / Faux. Parfait pour des états : publié, actif, validé.
ForeignKey
Relation plusieurs-à-un. Relie un article à un auteur, une commande à un client.

Appliquer les modifications à la base de données

Après toute modification du fichier models.py, vous devez toujours exécuter les deux commandes suivantes :

python manage.py makemigrations   # génère les fichiers de migration
python manage.py migrate          # applique les migrations à la BDD
⚠ Ne supprimez jamais manuellement les fichiers dans le dossier migrations/. Ces fichiers tracent l'historique complet de votre base de données et sont indispensables au déploiement.

5. urls.py : le routeur de votre application

Le routage dans Django fonctionne à deux niveaux (le fichier urls.py du projet principal inclut les URLs des apps). Chaque app possède son propre urls.py pour rester modulaire.

urls.py du projet principal (monprojet/urls.py)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),  # délègue à l'app blog
]

urls.py de l'app blog (blog/urls.py) : à créer manuellement

from django.urls import path
from . import views

app_name = 'blog'  # namespace pour éviter les conflits de noms

urlpatterns = [
    path('', views.liste_articles, name='liste'),
    path('/', views.detail_article, name='detail'),
]

Le paramètre name est crucial : il vous permet d'utiliser {% url 'blog:liste' %} dans vos templates sans coder l'URL en dur : vos liens restent valides même si vous changez la structure des URLs.

💡 La syntaxe <int:pk> est un convertisseur de type : Django capturera un entier dans l'URL et le passera à la vue sous le nom pk (primary key). Il existe aussi <str:slug>, <uuid:id>, etc.

6. views.py : la logique applicative

Le fichier views.py contient des fonctions (ou des classes) qui reçoivent une requête HTTP et retournent une réponse HTTP. C'est ici que vit la logique de votre application : récupération des données, vérification des permissions, traitement des formulaires.

Vues basées sur des fonctions (FBV)

from django.shortcuts import render, get_object_or_404
from .models import Article

def liste_articles(request):
    articles = Article.objects.filter(publie=True)
    return render(request, 'blog/liste.html', {'articles': articles})

def detail_article(request, pk):
    article = get_object_or_404(Article, pk=pk, publie=True)
    return render(request, 'blog/detail.html', {'article': article})

Vues basées sur des classes (CBV) : version avancée

Pour les opérations CRUD classiques, Django propose des vues génériques qui réduisent considérablement la quantité de code à écrire :

from django.views.generic import ListView, DetailView
from .models import Article

class ListeArticles(ListView):
    model = Article
    template_name = 'blog/liste.html'
    context_object_name = 'articles'
    queryset = Article.objects.filter(publie=True)

class DetailArticle(DetailView):
    model = Article
    template_name = 'blog/detail.html'
💡 Pour débuter, les FBV (fonctions) sont plus lisibles et plus faciles à comprendre. Les CBV (classes) deviennent utiles quand vous remarquez que vous répétez toujours les mêmes patterns.

7. Les templates : l'affichage HTML

Les templates sont des fichiers HTML enrichis d'un langage de gabarit (DTL : Django Template Language). Ils se trouvent dans le dossier templates/ de votre app, lui-même dans un sous-dossier portant le nom de l'app (convention recommandée).

Template de liste d'articles (blog/templates/blog/liste.html)

<!-- Héritage de template -->
{% extends "base.html" %}


  <h1>Tous les articles</h1>

  
    <p>Aucun article publié pour l'instant.</p>
  

Les balises et filtres essentiels du DTL

Affiche une variable passée par la Vue dans le contexte.
{% tag %}
Balise de logique : {% if %}, {% for %}, {% block %}, {% url %}.
{{ val|filtre }}
Transforme une valeur : |date, |lower, |truncatewords:20.
{% extends %}
Hérite d'un template parent pour éviter la duplication de code (header, footer…).
💡 La convention templates/blog/liste.html (dossier intermédiaire avec le nom de l'app) est indispensable dès que plusieurs apps ont des templates portant le même nom (ex. deux apps avec un index.html). Django pourrait charger le mauvais fichier sans cette organisation.

8. admin.py : l'interface d'administration

L'un des atouts majeurs de Django est son interface d'administration générée automatiquement. Pour rendre un modèle accessible depuis /admin, déclarez-le dans admin.py :

from django.contrib import admin
from .models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display = ['titre', 'date_publication', 'publie']
    list_filter = ['publie', 'date_publication']
    search_fields = ['titre', 'contenu']
    list_editable = ['publie']
    prepopulated_fields = {'slug': ('titre',)}  # si vous avez un champ slug

La classe ModelAdmin accepte de nombreuses options de personnalisation. Avec seulement quelques lignes, vous obtenez une interface de gestion complète avec recherche, filtres et édition en ligne.

9. forms.py : gérer les formulaires

Django propose un système de formulaires puissant qui gère automatiquement la validation des données, la protection CSRF et la liaison avec les modèles. Le fichier forms.py n'est pas créé automatiquement : vous devez le créer quand votre app nécessite des formulaires.

from django import forms
from .models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['titre', 'contenu', 'publie']
        widgets = {
            'contenu': forms.Textarea(attrs={'rows': 10}),
        }
        labels = {
            'titre': 'Titre de l\'article',
            'publie': 'Publier immédiatement',
        }

Un ModelForm est lié directement à un modèle : il génère les champs du formulaire à partir du modèle et peut sauvegarder directement l'objet avec form.save().

10. Quand créer de nouveaux fichiers et dossiers ?

Au fil du développement, votre projet va grandir et certains fichiers deviendront trop volumineux. Voici les règles pratiques pour savoir quand et quoi créer :

urls.py (app)
À créer dès que vous avez au moins une Vue dans une app. Ne mettez pas toutes vos URLs dans le fichier du projet.
forms.py
À créer dès que vous avez un formulaire. Ne définissez pas vos formulaires dans views.py.
serializers.py
À créer si vous construisez une API REST (avec Django REST Framework). Sérialise vos modèles en JSON.
signals.py
À créer pour les événements asynchrones : envoyer un email à la création d'un utilisateur, par exemple.
utils.py
Fonctions utilitaires réutilisables qui n'appartiennent ni à un modèle ni à une vue (calculs, formatage…).
constants.py
Centralise les constantes de l'app : listes de choix, codes statuts, paramètres fixes.
views/ (dossier)
Quand views.py dépasse ~200 lignes, découpez-le en sous-fichiers thématiques dans un dossier views/.
static/ (dossier)
CSS, JS, images propres à votre app. Structure : static/blog/css/style.css.
⚠ Un views.py de 500 lignes ou un models.py avec 15 classes sont des signaux d'alarme. Découpez l'app en plusieurs apps Django distinctes selon le principe de responsabilité unique.

11. Organisation recommandée pour un projet réel

Voici la structure cible d'un projet Django bien organisé, avec plusieurs apps et tous les fichiers essentiels :

monprojet/
  ├── monprojet/ ← configuration du projet
  │   ├── settings.py
  │   ├── urls.py
  │   └── wsgi.py
  ├── blog/ ← app blog
  │   ├── migrations/
  │   ├── templates/blog/
  │   ├── static/blog/
  │   ├── admin.py
  │   ├── forms.py
  │   ├── models.py
  │   ├── urls.py
  │   └── views.py
  ├── users/ ← app authentification
  ├── templates/ ← templates globaux (base.html…)
  ├── static/ ← fichiers statiques globaux
  ├── requirements.txt
  ├── .env ← variables d'environnement (SECRET_KEY…)
  └── manage.py

Conclusion : vous avez maintenant la carte du territoire

L'architecture Django MVT peut sembler complexe au premier regard, mais elle suit une logique claire et cohérente. Chaque fichier a un rôle précis, et Django vous guide naturellement vers une organisation saine. La clé est de respecter le principe de séparation des responsabilités : les Models gèrent les données, les Views la logique, les Templates l'affichage.

Dans le prochain article, nous construirons pas à pas un blog complet avec Django : création des modèles, configuration de l'admin, écriture des vues et des templates, et gestion des URLs. Restez connectés !


Mots-clés : architecture Django MVT, models.py Django, views.py Django, urls.py Django, templates Django, forms.py, ORM Django, django-admin, tutoriel Django intermédiaire, framework Python web