CONCEPTS DE BASE : PYTHON &
DJANGO
PARTIE 1 : PYTHON FONDAMENTAUX
Qu'est-ce que Python ?
Python est un langage de programmation **interprété** (pas de compilation),
**dynamiquement typé** (pas besoin de déclarer les types), et **multi-paradigme**
(orienté objet, fonctionnel, impératif).
**Avantages** :
Syntaxe simple et lisible (proche de l'anglais)
Énorme écosystème de bibliothèques
Très utilisé en Data Science, IA, Web, Automation
Rapide à développer (prototypage rapide)
**Comparaison avec Java** :
# PYTHON - Simple et concis
def calculer_moyenne(notes):
return sum(notes) / len(notes)
moyenne = calculer_moyenne([15, 18, 12])
print(f"Moyenne : {moyenne}")
// JAVA - Plus verbeux
public class Main {
public static double calculerMoyenne(List<Integer> notes) {
return [Link]()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
}
public static void main(String[] args) {
List<Integer> notes = [Link](15, 18, 12);
double moyenne = calculerMoyenne(notes);
[Link]("Moyenne : " + moyenne);
}
}
1. Types de Données Basiques
# Nombres
age = 25 # int
prix = 19.99 # float
# Chaînes de caractères
nom = "Zakarya"
prenom = 'Boufatmi'
message = f"Bonjour {nom}" # f-string (comme Template literals en JS)
# Booléens
est_actif = True
est_admin = False
# None (équivalent de null en Java)
valeur = None
**Différence avec Java** :
Pas besoin de déclarer le type : `age = 25` au lieu de `int age = 25;`
Pas de point-virgule à la fin
Indentation obligatoire (pas de `{}`)
2. Collections (Structures de Données)
Lists (≈ ArrayList en Java)
# Créer une liste
notes = [15, 18, 12, 16]
fruits = ["pomme", "banane", "orange"]
# Accès par index
premier = notes[0] # 15
dernier = notes[-1] # 16 (index négatif = depuis la fin)
# Ajouter/Supprimer
[Link](14) # Ajouter à la fin
[Link](0, 20) # Insérer à l'index 0
[Link](12) # Supprimer la valeur 12
element = [Link]() # Retirer et retourner le dernier
# Méthodes utiles
longueur = len(notes) # Taille de la liste
est_present = 15 in notes # Vérifier présence
[Link]() # Trier sur place
Dictionaries (≈ HashMap en Java)
# Créer un dictionnaire (clé-valeur)
utilisateur = {
"nom": "Boufatmi",
"prenom": "Zakarya",
"age": 25,
"email": "zakarya@[Link]"
}
# Accès aux valeurs
nom = utilisateur["nom"] # "Boufatmi"
age = [Link]("age") # 25
defaut = [Link]("ville", "N/A") # "N/A" si clé absente
# Modifier/Ajouter
utilisateur["age"] = 26
utilisateur["ville"] = "Rabat"
# Parcourir
for cle, valeur in [Link]():
print(f"{cle}: {valeur}")
Tuples (≈ Liste immuable)
# Tuple = liste non modifiable
coordonnees = (33.5731, -7.5898) # (latitude, longitude)
x, y = coordonnees # Unpacking
# Utile pour retourner plusieurs valeurs
def get_user():
return ("Zakarya", 25, "zakarya@[Link]")
nom, age, email = get_user()
Sets (≈ HashSet en Java)
# Set = collection unique, non ordonnée
competences = {"Java", "Spring", "Angular", "Python"}
# Opérations ensemblistes
[Link]("Django")
[Link]("Java")
a_python = "Python" in competences # True
3. Structures de Contrôle
If/Elif/Else
score = 85
if score >= 90:
mention = "Excellent"
elif score >= 75:
mention = "Bien"
elif score >= 60:
mention = "Assez bien"
else:
mention = "Insuffisant"
print(mention)
**Différences avec Java** :
Pas de parenthèses autour de la condition
`:` à la fin de chaque ligne de condition
Indentation obligatoire (pas de `{}`)
Boucles
# For sur une liste
notes = [15, 18, 12, 16]
for note in notes:
print(note)
# For avec range (comme for(int i=0; i<10; i++) en Java)
for i in range(10): # 0 à 9
print(i)
for i in range(5, 10): # 5 à 9
print(i)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8 (pas de 2)
print(i)
# While
compteur = 0
while compteur < 5:
print(compteur)
compteur += 1
# List comprehension (super puissant!)
carres = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, ...]
pairs = [x for x in range(20) if x % 2 == 0] # [0, 2, 4, 6, ...]
4. Fonctions
# Fonction simple
def saluer(nom):
return f"Bonjour {nom}!"
message = saluer("Zakarya")
# Paramètres par défaut
def creer_utilisateur(nom, age=18, actif=True):
return {
"nom": nom,
"age": age,
"actif": actif
}
user1 = creer_utilisateur("Alice") # age=18, actif=True
user2 = creer_utilisateur("Bob", 25) # actif=True
user3 = creer_utilisateur("Charlie", actif=False)
# Arguments nommés (comme en Kotlin)
user4 = creer_utilisateur(nom="David", actif=False, age=30)
# *args et **kwargs (varargs)
def somme(*nombres): # Accepte nombre variable d'arguments
return sum(nombres)
total = somme(1, 2, 3, 4, 5) # 15
def afficher_info(**kwargs): # Accepte arguments nommés variables
for cle, valeur in [Link]():
print(f"{cle}: {valeur}")
afficher_info(nom="Zakarya", age=25, ville="Rabat")
5. Classes et Objets
# Définir une classe
class Utilisateur:
# Constructeur (__init__ = constructor en Java)
def __init__(self, nom, email):
[Link] = nom # self = this en Java
[Link] = email
[Link] = True
# Méthode d'instance
def afficher(self):
statut = "actif" if [Link] else "inactif"
return f"{[Link]} ({[Link]}) - {statut}"
# Méthode d'instance
def desactiver(self):
[Link] = False
# Utilisation
user = Utilisateur("Zakarya", "zakarya@[Link]")
print([Link]())
[Link]()
print([Link]())
**Héritage** :
class Manager(Utilisateur):
def __init__(self, nom, email, equipe):
super().__init__(nom, email) # Appeler constructeur parent
[Link] = equipe
def afficher(self): # Override
base = super().afficher()
return f"{base} - Équipe: {[Link]}"
manager = Manager("Alice", "alice@[Link]", "IT")
print([Link]())
6. Gestion des Fichiers
# Lire un fichier
with open('[Link]', 'r') as f:
contenu = [Link]()
print(contenu)
# Le 'with' ferme automatiquement le fichier (comme try-with-resources en Java)
# Lire ligne par ligne
with open('[Link]', 'r') as f:
for ligne in f:
print([Link]())
# Écrire dans un fichier
with open('[Link]', 'w') as f:
[Link]("Bonjour monde\n")
[Link]("Deuxième ligne\n")
# Ajouter à la fin
with open('[Link]', 'a') as f:
[Link]("Ligne ajoutée\n")
7. Modules et Imports
# Importer un module entier
import math
resultat = [Link](16) # 4.0
# Importer des fonctions spécifiques
from math import sqrt, pi
resultat = sqrt(16)
aire = pi * (5 ** 2)
# Importer avec alias
import pandas as pd
import numpy as np
df = [Link](...)
# Importer vos propres modules
# fichier: [Link]
def calculer_moyenne(notes):
return sum(notes) / len(notes)
# Dans un autre fichier
from utils import calculer_moyenne
moyenne = calculer_moyenne([15, 18, 12])
8. Gestion des Exceptions
# Try/Except (comme try/catch en Java)
try:
age = int(input("Entrez votre âge: "))
resultat = 100 / age
except ValueError:
print("Veuillez entrer un nombre valide")
except ZeroDivisionError:
print("L'âge ne peut pas être 0")
except Exception as e: # Catch all
print(f"Erreur: {e}")
else: # Exécuté si aucune exception
print(f"Résultat: {resultat}")
finally: # Toujours exécuté
print("Fin du traitement")
# Lever une exception
def verifier_age(age):
if age < 0:
raise ValueError("L'âge ne peut pas être négatif")
return age
9. Bibliothèques Essentielles
pandas (Manipulation de données)
import pandas as pd
# Créer un DataFrame (comme une table Excel)
data = {
'nom': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'salaire': [50000, 60000, 70000]
}
df = [Link](data)
# Afficher
print(df)
print([Link]()) # 5 premières lignes
# Filtrer
jeunes = df[df['age'] < 30]
# Grouper et agréger
moyenne_salaire = [Link]('age')['salaire'].mean()
# Lire/Écrire fichiers
df = pd.read_csv('[Link]')
df = pd.read_excel('[Link]')
df.to_csv('[Link]', index=False)
requests (Appels HTTP/API)
import requests
# GET
response = [Link]('[Link]
if response.status_code == 200:
data = [Link]()
print(data)
# POST
nouvelle_donnee = {
'nom': 'Zakarya',
'email': 'zakarya@[Link]'
}
response = [Link](
'[Link]
json=nouvelle_donnee,
headers={'Authorization': 'Bearer TOKEN'}
)
PARTIE 2 : DJANGO FONDAMENTAUX
Qu'est-ce que Django ?
Django est un **framework web Python** qui suit le pattern **MVT** (Model-View-
Template) - équivalent du MVC.
**Philosophie** : "Batteries included" = tout est inclus d'office
ORM intégré (pas besoin de library externe)
Admin panel automatique
Authentification/Autorisation
Migrations de base de données
Formulaires
Validation
**Comparaison avec Spring Boot** :
Django ≈ Spring Boot
-----------------------------------------
Model (ORM) ≈ JPA Entity
View (Logic) ≈ Controller
Template (HTML) ≈ Thymeleaf/JSP
[Link] ≈ @RequestMapping
[Link] ≈ [Link]
[Link] ≈ mvn/gradle
1. Structure d'un Projet Django
mon_projet/
├── [Link] # CLI pour gérer le projet
├── mon_projet/ # Configuration du projet
│ ├── __init__.py
│ ├── [Link] # Configuration (DB, apps, middleware)
│ ├── [Link] # Routes principales
│ └── [Link] # Déploiement
└── mon_app/ # Application Django
├── __init__.py
├── [Link] # Modèles de données (≈ Entity)
├── [Link] # Logique métier (≈ Controller)
├── [Link] # Routes de l'app
├── [Link] # Configuration admin panel
├── [Link] # Configuration de l'app
├── [Link] # Tests unitaires
└── migrations/ # Migrations DB
└── __init__.py
**Créer un projet** :
# Installer Django
pip install django
# Créer un projet
django-admin startproject mon_projet
# Créer une app
cd mon_projet
python [Link] startapp mon_app
# Lancer le serveur
python [Link] runserver
2. Models (≈ JPA Entities)
**[Link]** :
from [Link] import models
class Utilisateur([Link]):
# Champs
nom = [Link](max_length=100)
email = [Link](unique=True)
age = [Link]()
date_creation = [Link](auto_now_add=True)
actif = [Link](default=True)
# Méthodes
def __str__(self):
return [Link]
class Meta:
db_table = 'utilisateurs'
ordering = ['-date_creation'] # Tri par défaut
class Competence([Link]):
nom = [Link](max_length=100)
description = [Link]()
def __str__(self):
return [Link]
class Evaluation([Link]):
# Relations (ForeignKey = ManyToOne)
utilisateur = [Link](
Utilisateur,
on_delete=[Link], # Si user supprimé, évals supprimées
related_name='evaluations' # [Link]()
)
competence = [Link](
Competence,
on_delete=[Link]
)
# Champs
note = [Link]()
date_evaluation = [Link]()
class Meta:
unique_together = ['utilisateur', 'competence', 'date_evaluation']
**Équivalent Java/JPA** :
@Entity
@Table(name = "utilisateurs")
public class Utilisateur {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
@Column(length = 100)
private String nom;
@Column(unique = true)
private String email;
private Integer age;
@Column(name = "date_creation")
private LocalDateTime dateCreation;
private Boolean actif = true;
@OneToMany(mappedBy = "utilisateur", cascade = [Link])
private List<Evaluation> evaluations;
}
3. Migrations (≈ Flyway/Liquibase)
# Créer des migrations basées sur les changements de models
python [Link] makemigrations
# Appliquer les migrations
python [Link] migrate
# Voir l'état des migrations
python [Link] showmigrations
# Générer le SQL sans l'exécuter
python [Link] sqlmigrate mon_app 0001
Django **génère automatiquement** les migrations en comparant vos models avec la DB.
4. ORM Django (Queries)
# CREATE
user = [Link](
nom="Zakarya",
email="zakarya@[Link]",
age=25
)
# READ
# Tous les utilisateurs
tous = [Link]()
# Filtrer
actifs = [Link](actif=True)
jeunes = [Link](age__lt=30) # age < 30
zakarya = [Link](nom__icontains="zakarya") # LIKE '%zakarya
%'
# Un seul résultat
user = [Link](id=1)
user = [Link](email="zakarya@[Link]")
# Existe?
existe = [Link](email="test@[Link]").exists()
# Compter
nb_users = [Link]()
nb_actifs = [Link](actif=True).count()
# UPDATE
user = [Link](id=1)
[Link] = 26
[Link]()
# Ou en masse
[Link](actif=False).update(actif=True)
# DELETE
user = [Link](id=1)
[Link]()
# Ou en masse
[Link](actif=False).delete()
# Relations (JOIN)
# Récupérer user avec ses évaluations
user = [Link].prefetch_related('evaluations').get(id=1)
for eval in [Link]():
print([Link])
# Agrégation
from [Link] import Avg, Count, Sum
stats = [Link](
moyenne_age=Avg('age'),
total=Count('id')
)
# Group By
from [Link] import Count
par_age = [Link]('age').annotate(
count=Count('id')
)
**Équivalent Spring Data JPA** :
// Django: [Link](actif=True)
// Spring:
List<Utilisateur> actifs = [Link]();
// Django: [Link](email="test@[Link]")
// Spring:
Optional<Utilisateur> user =
[Link]("test@[Link]");
// Django: [Link](age__lt=30)
// Spring:
List<Utilisateur> jeunes = [Link](30);
5. Views (≈ Controllers Spring)
**[Link]** :
from [Link] import JsonResponse, HttpResponse
from [Link] import render, get_object_or_404
from .models import Utilisateur
# Vue simple
def accueil(request):
return HttpResponse("Bienvenue!")
# Vue avec template
def liste_utilisateurs(request):
utilisateurs = [Link]()
return render(request, 'utilisateurs/[Link]', {
'utilisateurs': utilisateurs
})
# Vue détail
def detail_utilisateur(request, user_id):
user = get_object_or_404(Utilisateur, id=user_id)
return render(request, 'utilisateurs/[Link]', {
'utilisateur': user
})
# Vue JSON (API)
def api_utilisateurs(request):
users = [Link]()
data = {
'count': [Link](),
'results': [
{
'id': [Link],
'nom': [Link],
'email': [Link],
'age': [Link]
}
for u in users
]
}
return JsonResponse(data)
# Vue avec POST
from [Link] import csrf_exempt
import json
@csrf_exempt
def creer_utilisateur(request):
if [Link] == 'POST':
data = [Link]([Link])
user = [Link](
nom=data['nom'],
email=data['email'],
age=data['age']
)
return JsonResponse({
'id': [Link],
'message': 'Utilisateur créé'
}, status=201)
return JsonResponse({'error': 'Méthode non autorisée'}, status=405)
6. URLs (Routing)
**[Link]** (app) :
from [Link] import path
from . import views
urlpatterns = [
path('', [Link], name='accueil'),
path('utilisateurs/', views.liste_utilisateurs, name='liste_users'),
path('utilisateurs/<int:user_id>/', views.detail_utilisateur,
name='detail_user'),
path('api/utilisateurs/', views.api_utilisateurs, name='api_users'),
path('api/utilisateurs/create/', views.creer_utilisateur,
name='create_user'),
]
**[Link]** (projet principal) :
from [Link] import admin
from [Link] import path, include
urlpatterns = [
path('admin/', [Link]),
path('', include('mon_app.urls')), # Inclure les URLs de l'app
]
**Équivalent Spring Boot** :
@RestController
@RequestMapping("/api/utilisateurs")
public class UtilisateurController {
@GetMapping
public List<Utilisateur> liste() { ... }
@GetMapping("/{id}")
public Utilisateur detail(@PathVariable Long id) { ... }
@PostMapping
public Utilisateur create(@RequestBody Utilisateur user) { ... }
}
7. Django REST Framework (API)
Pour créer des APIs professionnelles, on utilise **Django REST Framework**.
**Installation** :
pip install djangorestframework
**[Link]** (≈ DTO en Spring) :
from rest_framework import serializers
from .models import Utilisateur
class UtilisateurSerializer([Link]):
class Meta:
model = Utilisateur
fields = ['id', 'nom', 'email', 'age', 'actif', 'date_creation']
# Ou tous les champs:
# fields = '__all__'
# Champs en lecture seule
read_only_fields = ['id', 'date_creation']
**[Link]** (avec ViewSet) :
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Utilisateur
from .serializers import UtilisateurSerializer
class UtilisateurViewSet([Link]):
queryset = [Link]()
serializer_class = UtilisateurSerializer
# Endpoint personnalisé: GET /api/utilisateurs/actifs/
@action(detail=False, methods=['get'])
def actifs(self, request):
actifs = [Link](actif=True)
serializer = self.get_serializer(actifs, many=True)
return Response([Link])
# Endpoint personnalisé: POST /api/utilisateurs/{id}/desactiver/
@action(detail=True, methods=['post'])
def desactiver(self, request, pk=None):
user = self.get_object()
[Link] = False
[Link]()
return Response({'status': 'utilisateur désactivé'})
**[Link]** :
from rest_framework.routers import DefaultRouter
from .views import UtilisateurViewSet
router = DefaultRouter()
[Link](r'utilisateurs', UtilisateurViewSet)
urlpatterns = [Link]
# Génère automatiquement:
# GET /utilisateurs/ -> liste
# POST /utilisateurs/ -> create
# GET /utilisateurs/{id}/ -> detail
# PUT /utilisateurs/{id}/ -> update
# DELETE /utilisateurs/{id}/ -> delete
# GET /utilisateurs/actifs/ -> custom action
8. Admin Panel (Bonus Django!)
Django génère automatiquement un panel d'administration.
**[Link]** :
from [Link] import admin
from .models import Utilisateur, Competence, Evaluation
@[Link](Utilisateur)
class UtilisateurAdmin([Link]):
list_display = ['nom', 'email', 'age', 'actif', 'date_creation']
list_filter = ['actif', 'date_creation']
search_fields = ['nom', 'email']
ordering = ['-date_creation']
[Link](Competence)
[Link](Evaluation)
**Créer un super utilisateur** :
python [Link] createsuperuser
# Nom: admin
# Email: admin@[Link]
# Password: ***
Accéder à : `[Link]
9. [Link] (Configuration)
# [Link]
# Base de données
DATABASES = {
'default': {
'ENGINE': '[Link]',
'NAME': 'ma_base',
'USER': 'postgres',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Apps installées
INSTALLED_APPS = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'rest_framework', # Django REST Framework
'mon_app', # Votre app
]
# Middleware
MIDDLEWARE = [
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
'[Link]',
]
# Langue et timezone
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Africa/Casablanca'
# REST Framework config
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':
'rest_framework.[Link]',
'PAGE_SIZE': 10,
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.[Link]',
],
}
COMPARAISON DJANGO vs SPRING BOOT
|----------------|--------|-------------|
RÉSUMÉ POUR L'ENTRETIEN
**Python en 3 phrases** :
Langage interprété, dynamiquement typé, syntaxe simple
Énorme écosystème (pandas, numpy, scikit-learn, etc.)
Très utilisé en Data Science, IA, Web (Django/Flask)
**Django en 3 phrases** :
Framework web Python MVT (Model-View-Template)
"Batteries included" : ORM, admin, auth, migrations intégrés
Django REST Framework = équivalent de Spring Boot pour APIs
**Concepts transférables** :
ORM : JPA ≈ Django ORM
API REST : Spring Controllers ≈ Django ViewSets
Routing : @RequestMapping ≈ [Link]
DTO : Spring DTO ≈ Django Serializers
Migrations : Flyway ≈ Django migrations
**Ce que tu peux dire** :
"Je n'ai pas encore pratiqué Django mais j'ai étudié l'architecture. Je vois beaucoup de
similarités avec Spring Boot : l'ORM est similaire à JPA, les ViewSets ressemblent aux
Controllers REST, et le système de migrations est comparable à Flyway. Les concepts
fondamentaux sont transférables, et Python étant plus simple syntaxiquement que Java, je
suis confiant de pouvoir monter en compétences rapidement."