diff --git a/source/images/django/django-first-template.png b/source/images/django/django-first-template.png new file mode 100644 index 0000000..f9f4aeb Binary files /dev/null and b/source/images/django/django-first-template.png differ 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.