Python
Django
Fastapi
Debutant
Django-Models
Django-Orm
Fastapi-Routes
Pydantic
Python-Debutant
Entretien-Python
Qcm-Python
Django-Views
Fastapi-Debutant
Python-Web
📝
Python Django/FastAPI Débutant — Routes & Modèles
20 questions sur les bases de Python, Django (modèles, vues, ORM) et FastAPI (routes, schemas Pydantic). Idéal pour préparer un premier entretien développeur Python web.
Banque de révision : les 60 questions corrigées
Voici l'intégralité des 60 questions de « Python Django/FastAPI Débutant — Routes & Modèles », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.
Explication :
En Python, le type
str représente les chaînes de caractères. Contrairement à d'autres langages, il n'existe pas de type char (un caractère unique est simplement un str de longueur 1). int = entier, float = décimal.
Explication :
[] crée une liste vide. {} crée un dictionnaire vide (ou un set si non vide). () crée un tuple vide. Python n'a pas de mot-clé new.
Explication :
En Python, on utilise le mot-clé
def suivi du nom de la fonction et de parenthèses. Le corps est indenté (pas de {}). Exemple : def add(a, b): return a + b.
Explication :
Python utilise
# pour les commentaires sur une ligne. Pour les commentaires multi-lignes, on peut utiliser des triple guillemets """...""" (docstrings). Les syntaxes // et /**/ sont pour Java/JS/C.
Explication :
== compare les valeurs. = est l'affectation. Python n'a pas === (c'est JavaScript). Pour comparer l'identité (même objet en mémoire), on utilise is.
Explication :
print() est la fonction d'affichage standard en Python 3. En Python 2, print était un statement (sans parenthèses). console.log() est JavaScript, echo est PHP/bash.
Explication :
d["key"] accède à la valeur. Si la clé n'existe pas, cela lève une KeyError. Pour éviter l'exception : d.get("key") (retourne None si absent) ou d.get("key", valeur_defaut).
Explication :
for x in liste: itère sur chaque élément. Python n'a pas de foreach. Pour itérer avec index : for i, x in enumerate(liste):. Pour un compteur : for i in range(10):.
Explication :
import os importe le module. Variantes : from os import path (import spécifique), import os as operating_system (alias), from os import * (tout importer, déconseillé).
Explication :
Liste (
[]) : mutable, on peut ajouter/modifier/supprimer des éléments. Tuple (()) : immuable, une fois créé, on ne peut pas le modifier. Les tuples sont plus rapides et peuvent être utilisés comme clés de dictionnaire (hashable).
En entretien : mentionner que les tuples sont hashable et donc utilisables comme clés de dict ou éléments de set, ce qui n'est pas le cas des listes.
Explication :
class MyClass: définit une classe. Pour l'héritage : class Child(Parent):. Le constructeur est def __init__(self, ...):. Le premier paramètre des méthodes d'instance est toujours self.
Explication :
len() retourne le nombre d'éléments. La liste [1, 2, 3] contient 3 éléments → résultat : 3. len() fonctionne aussi sur les strings (len("abc") == 3), tuples, dicts, etc.
Explication :
Python n'utilise pas de
() obligatoires autour de la condition (mais ils sont acceptés), ni de {}. La condition se termine par : et le bloc est indenté. elif (pas elseif), else:.
Explication :
range(5) génère les entiers de 0 à 4 (exclusif). range(start, stop, step) : range(1, 6) → 1 à 5, range(0, 10, 2) → 0, 2, 4, 6, 8. C'est un objet lazy (pas une liste directe).
Explication :
append(x) ajoute x en fin de liste. Pour insérer à un index : insert(index, x). Pour ajouter plusieurs éléments : extend([a, b, c]) ou += [a, b, c]. push() est JavaScript.
Explication :
Les f-strings (depuis Python 3.6) préfixent la chaîne avec
f et permettent d'interpoler des expressions entre {} : f"Bonjour {nom}, tu as {age} ans". Plus lisibles et performantes que format() ou %.
Mentionner les avantages : lisibilité, possibilité d'expressions complexes
f\"{2+2}\", appels de méthodes f\"{s.upper()}\".
Explication :
__init__.py (éventuellement vide) signale à Python que le dossier est un package importable. Sans ce fichier (en Python 2), le dossier n'est pas reconnu. En Python 3.3+, les namespace packages permettent des packages sans ce fichier, mais la convention reste de l'inclure.
Explication :
pip install django installe le paquet depuis PyPI. Autres usages : pip install django==4.2 (version spécifique), pip install -r requirements.txt (depuis un fichier), pip uninstall django, pip list (paquets installés).
Explication :
django-admin startproject mysite génère la structure initiale : manage.py, mysite/settings.py, mysite/urls.py, mysite/wsgi.py, mysite/asgi.py. Équivalent : python -m django startproject mysite.
Explication :
python manage.py startapp blog crée un sous-dossier blog/ avec models.py, views.py, admin.py, apps.py, tests.py et un dossier migrations/. L'app doit ensuite être ajoutée dans INSTALLED_APPS.
Explication :
La liste
INSTALLED_APPS dans settings.py référence toutes les applications actives. Exemple : 'blog.apps.BlogConfig' ou simplement 'blog'. Sans cette déclaration, Django ignore les modèles et migrations de l'application.
Explication :
Un modèle Django est une classe héritant de
models.Model. Chaque attribut de classe = une colonne en BDD. Django génère automatiquement le SQL et les migrations. Exemple : class Article(models.Model): titre = models.CharField(max_length=200).
Explication :
makemigrations analyse les changements dans models.py et génère des fichiers de migration dans migrations/. migrate applique ensuite ces migrations à la base de données. Toujours exécuter dans cet ordre : makemigrations puis migrate.
Explication :
python manage.py migrate exécute toutes les migrations en attente sur la base configurée dans settings.py > DATABASES. Avec un nom d'app : migrate blog. Pour revenir en arrière : migrate blog 0001 (rollback).
Explication :
L'ORM (Object-Relational Mapper) de Django traduit les opérations Python en SQL. On manipule des objets Python au lieu d'écrire du SQL :
Article.objects.filter(titre__contains='Python') génère SELECT ... WHERE titre LIKE '%Python%'. Support de SQLite, PostgreSQL, MySQL, Oracle.
En entretien, mentionner les avantages (portabilité, sécurité anti-SQL injection) et les limites (requêtes complexes parfois moins optimales que SQL brut → utiliser
raw() ou extra()).
Explication :
CharField(max_length=200) est le champ texte court. Pour les textes longs sans limite fixe : TextField(). max_length est obligatoire pour CharField. En BDD : VARCHAR(200) pour CharField, TEXT pour TextField.
Explication :
python manage.py runserver lance le serveur sur http://127.0.0.1:8000/ par défaut. Avec port : runserver 8080. Avec IP : runserver 0.0.0.0:8000 (accessible sur le réseau). Ne jamais utiliser ce serveur en production.
Explication :
Dans
urls.py, on définit la liste urlpatterns avec des appels à path() ou re_path(). Exemple : path('articles/', views.liste, name='article-list'). Le fichier urls.py racine inclut les urls des apps via include('blog.urls').
Explication :
Une vue Django est simplement une fonction Python qui prend une
request et retourne un HttpResponse. Exemple : def index(request): return render(request, 'index.html', context). L'héritage n'est nécessaire que pour les Class-Based Views (CBV).
Explication :
render() est un raccourci Django qui combine loader.get_template() + template.render(context) + HttpResponse(). Le context est un dictionnaire transmis au template : {'articles': Article.objects.all()}.
Explication :
L'admin Django est une interface CRUD générée automatiquement accessible sur
/admin/. On enregistre les modèles avec admin.site.register(Article). Elle permet de lister, créer, modifier, supprimer des enregistrements sans écrire de code. Très personnalisable via ModelAdmin.
Mentionner que l'admin est excellent pour les back-offices internes, mais ne pas l'exposer publiquement sans protection (changer le préfixe URL, désactiver en production si non utilisé).
Explication :
python manage.py createsuperuser demande en interactif le nom d'utilisateur, l'email et le mot de passe. Ce compte aura accès à /admin/. On peut aussi créer des utilisateurs normaux depuis l'admin ou via User.objects.create_user().
Explication :
Dans
settings.py, le dictionnaire DATABASES configure la BDD. Par défaut : SQLite ('ENGINE': 'django.db.backends.sqlite3'). Pour PostgreSQL : 'ENGINE': 'django.db.backends.postgresql' avec NAME, USER, PASSWORD, HOST, PORT.
Explication :
FastAPI est un framework web Python moderne (2018) basé sur ASGI/Starlette, dédié principalement aux APIs. Points forts : support natif de
async/await, validation automatique via Pydantic, documentation Swagger/OpenAPI auto-générée, très haute performance (comparable à Node.js/Go).
Explication :
pip install fastapi[all] installe FastAPI + toutes les dépendances optionnelles (uvicorn, pydantic, etc.). L'installation minimale est pip install fastapi uvicorn. Uvicorn est le serveur ASGI (comme Gunicorn pour WSGI) requis pour lancer l'app FastAPI.
Explication :
On instancie la classe
FastAPI : from fastapi import FastAPI; app = FastAPI(). C'est l'objet central auquel on attache les routes. On peut passer des métadonnées : FastAPI(title='Mon API', version='1.0.0').
Explication :
FastAPI utilise des décorateurs HTTP :
@app.get('/'), @app.post('/'), @app.put('/'), @app.delete('/'), @app.patch('/'). La fonction Python dessous est la path operation function.
Explication :
uvicorn main:app --reload lance l'app. main = nom du fichier Python (sans .py), app = nom de l'instance FastAPI. --reload redémarre automatiquement si le code change (développement uniquement). En prod : sans --reload et avec plusieurs workers.
Explication :
FastAPI utilise
{nom_param} dans l'URL. La fonction doit avoir un paramètre du même nom : @app.get('/items/{item_id}')
def get_item(item_id: int): .... FastAPI valide et convertit automatiquement le type (ici str → int).
Explication :
Dans FastAPI, tout paramètre de fonction qui n'est pas dans l'URL est automatiquement un query parameter.
@app.get('/items/')
def list_items(skip: int = 0, limit: int = 10): ... → /items/?skip=0&limit=10. Les valeurs par défaut les rendent optionnels.
Explication :
Pydantic valide et sérialise des données via des annotations de type Python. FastAPI l'utilise pour valider les corps de requête, les réponses et les paramètres. On définit des schémas en héritant de
BaseModel : class Item(BaseModel): name: str; price: float.
En entretien : Pydantic v2 (utilisé par FastAPI 0.100+) est réécrit en Rust, 5-50x plus rapide que v1. Mentionner les validators, Field(), et model_config.
Explication :
FastAPI détecte automatiquement qu'un paramètre de type
BaseModel est un corps de requête JSON. Exemple : class Item(BaseModel): name: str
@app.post('/items/')
def create(item: Item): .... FastAPI valide le JSON reçu contre le schéma Pydantic.
Explication :
FastAPI génère automatiquement deux UIs :
/docs (Swagger UI, interactive) et /redoc (ReDoc, plus lisible). La spec OpenAPI brute est sur /openapi.json. Aucune configuration supplémentaire n'est nécessaire, c'est activé par défaut.
Explication :
Pour rendre un paramètre optionnel :
from typing import Optional
def f(q: Optional[str] = None) ou en Python 3.10+ : def f(q: str | None = None). La valeur par défaut None est obligatoire pour que le paramètre soit vraiment optionnel.
Explication :
async def déclare une coroutine. Elle doit être attendue avec await ou exécutée via asyncio.run(). Dans FastAPI, on peut utiliser async def ou def ordinaire pour les path operations — FastAPI gère les deux cas.
Explication :
models.DateTimeField() stocke une date et heure. Options utiles : auto_now_add=True (fixe la valeur à la création), auto_now=True (met à jour à chaque sauvegarde). Pour date seule : DateField(). Pour heure seule : TimeField().
Explication :
Article.objects.all() retourne un QuerySet de tous les articles. C'est une requête lazy (pas exécutée tant qu'on n'itère pas). Filtrer : filter(actif=True). Exclure : exclude(). Premier : first(). Compter : count().
Explication :
manage.py est le point d'entrée CLI de Django. Il configure DJANGO_SETTINGS_MODULE et permet d'exécuter des commandes : runserver, migrate, createsuperuser, shell, test, etc. Équivaut à django-admin dans le contexte du projet.
Explication :
Django : framework full-stack batteries-included (ORM, admin, auth, templates, formulaires) — idéal pour applications web complètes. FastAPI : micro-framework dédié APIs, async natif, très rapide, validation Pydantic, doc auto — idéal pour microservices et APIs REST/GraphQL modernes.
Mentionner que les deux peuvent cohabiter : Django pour le back-office, FastAPI pour l'API exposée publiquement. DRF (Django REST Framework) est aussi une alternative pour rester dans l'écosystème Django.
Explication :
Deux approches : (1) décorateur
@app.post('/', status_code=201) — simple et recommandé pour la doc. (2) return JSONResponse(content=..., status_code=201) — plus flexible. Pour les erreurs : lever HTTPException(status_code=404, detail='Not found').
Explication :
Django inclut
CsrfViewMiddleware (activé par défaut) et le tag template {% csrf_token %} à placer dans chaque formulaire HTML. Ce token unique par session empêche les attaques CSRF. Pour les APIs AJAX : envoyer le token dans le header X-CSRFToken.
Explication :
Django Template Language (DTL) utilise
{{ variable }} pour l'affichage et {% tag %} pour les tags logiques ({% if %}, {% for %}, {% block %}, etc.). Les filtres s'appliquent avec | : {{ titre|upper }}.
Explication :
{% extends 'base.html' %} indique que ce template hérite du template de base. Les blocs définis dans le parent ({% block content %}{% endblock %}) sont surchargés dans l'enfant. {% include %} insère un sous-template sans héritage.
Explication :
FastAPI retourne 200 OK par défaut pour toutes les routes. Pour les créations, la convention REST recommande 201 :
@app.post('/', status_code=201). FastAPI gère aussi automatiquement les codes d'erreur de validation (422) et les exceptions HTTP.
Explication :
from fastapi import HTTPException puis raise HTTPException(status_code=404, detail='Item not found'). FastAPI retourne automatiquement un JSON {"detail": "Item not found"}. On peut aussi créer des gestionnaires d'exceptions personnalisés avec @app.exception_handler().
Explication :
Dans
admin.py de l'app : from django.contrib import admin
from .models import Article
admin.site.register(Article). Pour personnaliser : créer une classe ArticleAdmin(admin.ModelAdmin) et passer admin.site.register(Article, ArticleAdmin).
Explication :
L'argument
default accepte une valeur statique ou une callable. Exemples : default='', default=0, default=True, default=list (liste vide), default=timezone.now (fonction appelée à chaque création).
Explication :
python manage.py shell ouvre un shell Python avec le contexte Django configuré (settings chargés, modèles accessibles). Idéal pour tester des requêtes ORM. Avec IPython si installé : shell plus riche. Avec --command : exécuter du code sans interactivité.
Explication :
Un environnement virtuel (
venv) isole les dépendances d'un projet : chaque projet a son propre Python et ses propres paquets. Créer : python -m venv env. Activer : env\Scripts\activate (Windows) ou source env/bin/activate (Linux/Mac).
Toujours utiliser un venv en développement. Mentionner aussi
poetry et pipenv comme alternatives modernes à pip + venv.
Explication :
requirements.txt liste les paquets nécessaires : Django==4.2.13
fastapi==0.111.0
uvicorn==0.30.0. Générer : pip freeze > requirements.txt. Installer : pip install -r requirements.txt. Facilite la reproduction de l'environnement.