From ec7d5825de432e6d3c1d1e747e7f30842a44f3ec Mon Sep 17 00:00:00 2001 From: Fred Date: Fri, 18 Dec 2020 21:35:00 +0100 Subject: [PATCH] Explains a basic Django cycle --- .../images/django/django-first-template.png | Bin 0 -> 14946 bytes source/part-1-workspace/django/_index.adoc | 102 ++++++++++++++++++ .../part-1-workspace/environment/_index.adoc | 2 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 source/images/django/django-first-template.png diff --git a/source/images/django/django-first-template.png b/source/images/django/django-first-template.png new file mode 100644 index 0000000000000000000000000000000000000000..f9f4aeb76e7c614d871734512d432b79edd858dc GIT binary patch literal 14946 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 literal 0 HcmV?d00001 diff --git a/source/part-1-workspace/django/_index.adoc b/source/part-1-workspace/django/_index.adoc index 816e3ba..695ed0a 100644 --- a/source/part-1-workspace/django/_index.adoc +++ b/source/part-1-workspace/django/_index.adoc @@ -327,9 +327,111 @@ La structure de vos répertoires devient celle-ci: ==== Fonctionement général +Le métier de programmeur est devenu de plus en plus complexe. Il y a 20 ans, nous pouvions nous contenter d'une simple page PHP dans laquelle nous mixions l'ensemble des actios à réaliser: requêtes en bases de données, construction de la page, ... +La recherche d'une solution a un problème n'était pas spécialement plus complexe - dans la mesure où le rendu des enregistrements en direct n'était finalement qu'une forme un chouia plus évoluée du `print()` ou des `System.out.println()` - mais c'était l'évolutivité des applications qui en prenait un coup: une grosse partie des tâches étaient dupliquées entre les différentes pages, et l'ajout d'une nouvelle fonctionnalité était relativement ardue. + +Django (et d'autres cadriciels) résolvent ce problème en se basant ouvertement sur le principe de `Don't repeat yourself` footnote:[DRY]. +Chaque morceau de code ne doit apparaitre qu'une seule fois, afin de limiter au maximum la redite (et donc, l'application d'un même correctif à différents endroits). + +Le chemin parcouru par une requête est expliqué en (petits) détails ci-dessous. + .How it works image::images/diagrams/django-how-it-works.png[] +*1. Un utilisateur ou un visiteur souhaite accéder à une URL hébergée et servie par notre application*. +Ici, nous prenons l'exemple de l'URL fictive `https://gwift/wishes/91827`. +Lorsque cette URL "arrive" dans notre application, son point d'entrée se trouvera au niveau des fichiers `asgi.py` ou `wsgi.py`. Nous verrons cette partie plus tard, et nous pouvons nous concentrer sur le chemin interne qu'elle va parcourir. + +*Etape 0* - La première étape consiste à vérifier que cette URL répond à un schéma que nous avons défini dans le fichier `gwift/urls.py`. + +*Etape 1* - Si ce n'est pas le cas, l'application n'ira pas plus loin et retournera une erreur à l'utilisateur. + + +*Etape 2* - Django va parcourir l'ensemble des _patterns_ présents dans le fichier `urls.py` et s'arrêtera sur le premier qui correspondra à la requête qu'il a reçue. +Ce cas est relativement trivial: la requête `/wishes/91827` a une correspondance au niveau de la ligne `path("wishes/` dans l'exemple ci-dessous. +Django va alors appeler la fonction footnote:[Qui ne sera pas toujours une fonction. Django s'attend à trouver un _callable_, c'est-à-dire n'importe quel élément qu'il peut appeler comme une fonction.] associée à ce _pattern_, c'est-à-dire `wish_details` du module `gwift.views`. + +[source,python] +---- +from django.contrib import admin +from django.urls import path + +from gwift.views import wish_details <1> + +urlpatterns = [ + path('admin/', admin.site.urls), + path("wishes/", wish_details), <2> +] +---- +<1> Nous importons la fonction `wish_details` du module `gwift.views` +<2> Champomy et cotillons! Nous avons une correspondance avec `wishes/details/91827` + + +Nous n'allons pas nous occuper de l'accès à la base de données pour le moment (nous nous en occuperons dans un prochain chapitre) et nous nous contenterons de remplir un canevas avec un ensemble de données. +Le module `gwift.views` qui se trouve dans le fichier `gwift/views.py` peut ressembler à ceci: + +[source,python] +---- +[...] + +from datetime import datetime + + +def wishes_details(request: HttpRequest, wish_id: int) -> HttpResponse: + context = { + "user_name": "Bond," + "user_first_name": "James", + "now": datetime.now() + } + + return render( + request, + "wish_details.html", + context + ) +---- + +Pour résumer, cette fonction permet: + +. De construire un _contexte_, qui est représenté sous la forme d'un dictionnaire associant des clés à des valeurs. Les clés sont respectivement `user_name`, `user_first_name` et `now`, tandis que leurs valeurs respectives sont `Bond`, `James` et le `moment présent` footnote:[Non, pas celui d'Eckhart Tolle]. +. Nous passons ensuite ce dictionnaire à un canevas, `wish_details.html` +. L'application du contexte sur le canevas nous donne un résultat. + +[source,html] +---- + + + + + Page title + + +

Hi!

+

My name is {{ user_name }}. {{ user_first_name }} {{ user_name }}.

+

This page was generated at {{ now }}

+ + +---- + +Après application de notre contexte sur ce template, nous obtiendrons ce document, qui sera renvoyé au navigateur de l'utilisateur qui aura fait la requête initiale: + +[source,html] +---- + + + + Page title + + +

Hi!

+

My name is Bond. James Bond.

+

This page was generated at 2027-03-19 19:47:38

+ + +---- + +.Résultat +image::images/django/django-first-template.png[] ==== 12 facteurs et configuration globale diff --git a/source/part-1-workspace/environment/_index.adoc b/source/part-1-workspace/environment/_index.adoc index 6ecf4e0..c94d11f 100644 --- a/source/part-1-workspace/environment/_index.adoc +++ b/source/part-1-workspace/environment/_index.adoc @@ -500,6 +500,6 @@ Il suffit alors de: Finalement, sachez qu'il existe plusieurs manières de gérer ces flux d'informations. Les plus connus sont https://www.gitflow.com/[Gitflow] et https://www.reddit.com/r/programming/comments/7mfxo6/a_branching_strategy_simpler_than_gitflow/[Threeflow]. -=== Décrire ses changements +==== Décrire ses changements -> parler de la bonne structure d'un commit.