diff --git a/django-initiation/django.md b/django-initiation/django.md index 00d9ffc..d6f8f27 100644 --- a/django-initiation/django.md +++ b/django-initiation/django.md @@ -6,23 +6,26 @@ Julien Palard https://mdk.fr -::: notes +notes: Introduce yourself! # Django -Django est une infrastructure d'applications web populaire et robuste. +Django est une infrastructure d’applications web populaire et robuste. > The web framework for perfectionists with deadlines. -## Django : qui l'utilise ? +## Django : qui l’utilise ? -- Instagram, Pineterest, Mozilla, Disqus, BitBucket, … - -![](static/stats.png) +- Instagram +- Pineterest +- Mozilla +- National Geographic +- [Washington Post](https://www.djangoproject.com/weblog/2005/dec/08/congvotes/) +- ... ## Vocabulaire @@ -55,18 +58,18 @@ Une fois dans le projet, pour créer une application, une commande : python manage.py startapp watch ``` -::: notes +notes: (et ajout dans `settings.py`) ## La théorie — Modèle -Un « modèle » est la description d'une table. +Un « modèle » est la description d’une table. Ça rappelle un ORM, mais ça permet beaucoup plus de choses en Django. -::: notes +notes: - admin - forms @@ -85,14 +88,14 @@ class Website(models.Model): last_check = models.DateTimeField(auto_now_add=True) ``` -::: notes +notes: -Prendre le temps d'expliquer les fields (leur relation avec la DB), et +Prendre le temps d’expliquer les fields (leur relation avec la DB), et les differents endroits ou Django peut reutiliser cette information (widgets, validation, ...). -## Première interface d'admin +## Première interface d’admin En une ligne, pourquoi pas : @@ -107,14 +110,14 @@ admin.site.register(Website) - sqlite - ... -::: notes +notes: -Leur faire croire 2 secondes qu'on va devoir s'installer et se +Leur faire croire 2 secondes qu’on va devoir s’installer et se configurer un serveur de base de donnée :D Leur expliquer que sqlite est utilisé dans les applications : pas -besoin d'installer un postgresql pour utiliser Firefox, pourtant -Firefox a besoin d'une base de donnée. +besoin d’installer un postgresql pour utiliser Firefox, pourtant +Firefox a besoin d’une base de donnée. ## La théorie — La DB @@ -124,15 +127,15 @@ python manage.py makemigrations python manage.py migrate ``` -::: notes +notes: On expliquera plus tard, leur dire que ça crée la DB et que le but -maintenant c'est surtout d'aller tester ça :) +maintenant c’est surtout d’aller tester ça :) -## L'interface d'administration +## L’interface d’administration -On a une DB, mais pas encore d'utilisateur admin dedans : +On a une DB, mais pas encore d’utilisateur admin dedans : ```bash python manage.py createsuperuser @@ -154,15 +157,15 @@ cd project python manage.py startapp watch ``` -::: notes +notes: -Biiien prendre le temps d'expliquer l'arborescence, de se promener, -d'y lire les commentaires. +Biiien prendre le temps d’expliquer l’arborescence, de se promener, +d’y lire les commentaires. ## La pratique -Ajout de l'app `watch` dans `project/settings.py` : +Ajout de l’app `watch` dans `project/settings.py` : ```python INSTALLED_APPS = [ @@ -185,7 +188,7 @@ class Website(models.Model): ``` -## Première interface d'admin +## Première interface d’admin Et ça dans `watch/admin.py`. @@ -204,19 +207,19 @@ python manage.py makemigrations python manage.py migrate ``` -::: notes +notes: Expliquer les deux étapes. ## Les modèles -Désambiguons `makemigrations` et `migrate` d'abord. +Désambiguons `makemigrations` et `migrate` d’abord. -## L'interface d'administration +## L’interface d’administration -On a une DB, mais pas encore d'utilisateur admin dedans : +On a une DB, mais pas encore d’utilisateur admin dedans : ```bash python manage.py createsuperuser @@ -224,31 +227,31 @@ python manage.py createsuperuser ## Terminé -On a terminé, on peut essayer maintenant ? +On a terminé, on peut essayer maintenant ? ```bash python manage.py runserver ``` -::: notes +notes: Leur faire faire ça dans un **autre** shell. -puis les laisser jouer avec l'interface d'admin, créer quelques sites... +puis les laisser jouer avec l’interface d’admin, créer quelques sites... -## L'interface d'administration +## L’interface d’administration -Les modèles, leurs `fields` ne servent donc pas qu'a l'ORM, cette -interface d'admin nous à demandé une ligne de code. +Les modèles, leurs `fields` ne servent donc pas qu’a l’ORM, cette +interface d’admin nous a demandé une ligne de code. -::: notes +notes: -Si ce n'est pas déjà fait, leur faire ajouter des `__str__`. +Si ce n’est pas déjà fait, leur faire ajouter des `__str__`. ## Astuce -On peut passer beaucoup de temps à peaufiner l'interface d'admin, +On peut passer beaucoup de temps à peaufiner l’interface d’admin, repoussez ça après avoir livré une première version. @@ -259,28 +262,28 @@ repoussez ça après avoir livré une première version. Créez le modèle `Check` avec les champs `is_up`, `date`, `website`, et `message`. -::: notes +notes: -Pour le champ `website` vous aurez besoin d'un `models.ForeignKey`, RTFM. +Pour le champ `website` vous aurez besoin d’un `models.ForeignKey`, RTFM. -## L'admin +## L’admin -Ajoutez une interface d'admin pour ce modèle, et ajoutez à la main quelques « *checks* ». +Ajoutez une interface d’admin pour ce modèle, et ajoutez à la main quelques « *checks* ». -::: notes +notes: Les faire tester ça. ## Personalisons -Dans chaque modèle, un `__str__` aide l'admin à être lisible. +Dans chaque modèle, un `__str__` aide l’admin à être lisible. ## Personalisons -Dans `admin.py` on peut préciser les colonnes qu'on veut afficher : +Dans `admin.py` on peut préciser les colonnes qu’on veut afficher : ```python @admin.register(Website) @@ -296,12 +299,12 @@ class CheckAdmin(admin.ModelAdmin): # Les URLs & les vues -Changons complètement de sujet : les URLs et des vues. +Changons complètement de sujet : les URLs et des vues. ## Les URLs -Dans `project/urls.py` on va se rajouter une URL pour la page d'accueil : +Dans `project/urls.py` on va se rajouter une URL pour la page d’accueil : ```python from watch import views @@ -313,9 +316,9 @@ urlpatterns = [ ] ``` -::: notes +notes: -C'est un `path`, un chemin, c'est le chemin vide. +C’est un `path`, un chemin, c’est le chemin vide. ## Les URLs @@ -341,18 +344,18 @@ from django.urls import include path("", include("watch.urls")), ``` -::: notes +notes: -C'est pratique pour « ancrer » un ensemble de chemin sous un autre -chemin : pour se faire une hierarchie. +C’est pratique pour « ancrer » un ensemble de chemin sous un autre +chemin : pour se faire une hierarchie. ## namespaces Les espaces de nommage permettent de désambiguer les urls nommées : -`index` est le nom de la page d'accueil de l'interface d'admin de la -page d'accueil de votre application... +`index` est le nom de la page d’accueil de l’interface d’admin ou de la +page d’accueil de votre application ? ## namespaces @@ -364,9 +367,9 @@ Avec les espaces de nommage, on a donc : sans ambiguité. -::: notes +notes: -Utiliez-en, c'est bien. +Utiliez-en, c’est bien. ## Les vues @@ -383,9 +386,9 @@ def index(request): ``` -::: notes +notes: -C'est bien mais écrire du HTML dans du Python c'est pas élégant. +C’est bien mais écrire du HTML dans du Python c’est pas élégant. ## Les vues @@ -425,7 +428,7 @@ Donc dans `watch/templates/watch/index.html` : ``` -::: notes +notes: La création du dossier `templates/` est typiquement quelque chose que `runserver` ne voit pas, il faut le redémarrer. @@ -433,7 +436,7 @@ La création du dossier `templates/` est typiquement quelque chose que ## Les vues -Et si on ajoutais de la données provenant de la DB dans le template ? +Et si on ajoutait de la donnée provenant de la DB dans le template ? ## Les vues @@ -447,18 +450,18 @@ def index(request): {"websites": Website.objects.all()}) ``` -::: notes +notes: Ne pas oublier les imports… -Premier apperçu de l'ORM en passant. +Premier apperçu de l’ORM en passant. ## Les vues Digression : -Il existe aussi des vues basées sur des classes, pouvant s'appuyer sur +Il existe aussi des vues basées sur des classes, pouvant s’appuyer sur des modèles. @@ -485,7 +488,7 @@ class WebsiteListView(ListView): ## Les templates -Ça fonctionne, mais on ne veux pas répéter l'entête HTML à chaque +Ça fonctionne, mais on ne veut pas répéter l’entête HTML à chaque page… @@ -505,14 +508,14 @@ En utilisant `extends`, on peut réutiliser des templates. python -m pip install django-debug-toolbar ``` -L'ajouter dans `settings.py` et `urls.py`. +L’ajouter dans `settings.py` et `urls.py`. -# L'ORM +# L’ORM -## L'ORM +## L’ORM -C'est l'occasion de sortir un `python manage.py shell`. +C’est l’occasion de sortir un `python manage.py shell`. ```pycon >>> from watch.models import Website @@ -524,8 +527,8 @@ Essayer `.all`, `.filter`, `.get`, `.order_by`, et les slices. ## Les *Managers* -Les *managers* représentent une table, il sont accessible via -l'attribut `objects` d'un modèle. +Les *managers* représentent une table, ils sont accessibles via +l’attribut `objects` d’un modèle. Ses opérations (des méthodes) renvoient des `queryset`s. @@ -543,7 +546,7 @@ Les instances de modèles représentent une ligne de la table. ## Les *Queryset* Représentent un ensemble de lignes de la base de donnée. Ils ont les -mêmes méthodes que les *managers* : +mêmes méthodes que les *managers* : - filter - get @@ -561,8 +564,8 @@ Out[3]: ]> ## Les *Queryset* -Pour ceux qui ont fait du SQL c'est un "lazy select" : c'est un -`SELECT` qui ne s'éxécutera que si nécessaire. +Pour ceux qui ont fait du SQL c’est un "lazy select" : c’est un +`SELECT` qui ne s’éxécutera que si nécessaire. ## Les *RelatedManager* @@ -577,7 +580,7 @@ Out[4]: , ]> # Forms -Comme pour l'admin, Django peut utiliser les informations des modèles +Comme pour l’admin, Django peut utiliser les informations des modèles pour vous aider à générer des formulaires. @@ -587,7 +590,7 @@ Créer un formulaire ressemble à créer un modèle, on décrit les champs : ```python class WebsiteForm(forms.Form): - host = forms.CharField(label='Website hostname', + host = forms.CharField(label="Website hostname", max_length=512) ``` @@ -610,7 +613,7 @@ On le donne au template : ## Forms -On l'affiche dans le template : +On l’affiche dans le template : ```html
@@ -639,7 +642,7 @@ class WebsiteForm(forms.ModelForm): ## Widgets -Le rendu HTML d'un champ de formulaire est appelé un `Widget`, il est +Le rendu HTML d’un champ de formulaire est appelé un `Widget`, il est possible de le changer, par exemple si vous préférez un `