Revert "Cleaned doc folder as it was unused"

This reverts commit 8716f2a01e.
This commit is contained in:
Théo DURR
2022-12-15 22:29:55 +01:00
parent 8716f2a01e
commit 6ce70abae5
116 changed files with 5882 additions and 0 deletions

60
doc/start/devtools.rst Normal file
View File

@@ -0,0 +1,60 @@
Configurer son environnement de développement
=============================================
Le projet n'est en aucun cas lié à un quelconque environnement de développement. Il est possible pour chacun de travailler avec les outils dont il a envie et d'utiliser l'éditeur de code avec lequel il est le plus à l'aise.
Pour donner une idée, Skia a écrit une énorme partie de projet avec l'éditeur *vim* sur du GNU/Linux alors que Sli a utilisé *Sublime Text* sur MacOS.
Configurer Black pour son éditeur
---------------------------------
Tous les détails concernant l'installation de black sont ici : https://black.readthedocs.io/en/stable/editor_integration.html
Néanmoins, nous tenterons de vous faire ici un résumé pour deux éditeurs de textes populaires que sont VsCode et Sublime Text.
.. sourcecode:: bash
# Installation de black
pip install black
VsCode
~~~~~~
.. warning::
Il faut installer black dans son environement virtuel pour cet éditeur
Black est directement pris en charge par l'extension pour le Python de VsCode, il suffit de rentrer la configuration suivante :
.. sourcecode:: json
{
"python.formatting.provider": "black",
"editor.formatOnSave": true
}
Sublime Text
~~~~~~~~~~~~
Il est tout d'abord nécessaire d'installer ce plugin : https://packagecontrol.io/packages/sublack.
Il suffit ensuite d'ajouter dans les settings du projet (ou directement dans les settings globales) :
.. sourcecode:: json
{
"sublack.black_on_save": true
}
Si vous utilisez le plugin `anaconda <http://damnwidget.github.io/anaconda/>`__, pensez à modifier les paramètres du linter pep8 pour éviter de recevoir des warnings dans le formatage de black comme ceci :
.. sourcecode:: json
{
"pep8_ignore": [
"E203",
"E266",
"E501",
"W503"
]
}

275
doc/start/hello_world.rst Normal file
View File

@@ -0,0 +1,275 @@
Créer une nouvelle application Hello World
==========================================
L'objectif de ce petit tutoriel est de prendre rapidement en main les vues, les urls et les modèles de Django. On créera une application nommée *hello* qui fournira une page affichant "Hello World", une autre page qui affichera en plus un numéro qui sera récupéré depuis l'URL ainsi qu'une page affichant un élément récupéré de la base de données, le tout au milieu d'une page typique du Sith AE.
Créer l'application
-------------------
La première étape est de crée l'application. Cela se fait très simplement avec les outils fournis par le framework.
.. code-block:: bash
./manage.py startapp hello
Il faut ensuite activer l'application dans les paramètres du projet en l'ajoutant dans la liste des applications installées.
.. code-block:: python
# sith/settings.py
# ...
INSTALLED_APPS = (
...
"hello",
)
Enfin, on vas inclure les URLs de cette application dans le projet sous le préfixe */hello/*.
.. code-block:: python
# sith/urls.py
urlpatterns = [
...
url(r"^hello/", include("hello.urls", namespace="hello", app_name="hello")),
]
Un Hello World simple
---------------------
Dans un premier temps, nous allons créer une vue qui vas charger un template en utilisant le système de vues basées sur les classes de Django.
.. code-block:: python
# hello/views.py
from django.views.generic import TemplateView
# Toute la logique pour servir la vue et parser le template
# est directement héritée de TemplateView
class HelloView(TemplateView):
template_name = "hello/hello.jinja" # On indique quel template utiliser
On vas ensuite créer le template.
.. code-block:: html+jinja
{# hello/templates/hello/hello.jinja #}
{# On étend le template de base du Sith #}
{% extends "core/base.jinja" %}
{# On remplis la partie titre du template étendu #}
{# Il s'agit du titre qui sera affiché dans l'onglet du navigateur #}
{% block title %}
Hello World
{% endblock title %}
{# On remplis le contenu de la page #}
{% block content %}
<p>Hello World !</p>
{% endblock content %}
Enfin, on crée l'URL. On veut pouvoir appeler la page depuis https://localhost:8000/hello, le préfixe indiqué précédemment suffit donc.
.. code-block:: python
# hello/urls.py
from django.conf.urls import url
from hello.views import HelloView
urlpatterns = [
# Le préfixe étant retiré lors du passage du routeur d'URL
# dans le fichier d'URL racine du projet, l'URL à matcher ici est donc vide
url(r"^$", HelloView.as_view(), name="hello"),
]
Et voilà, c'est fini, il ne reste plus qu'à lancer le serveur et à se rendre sur la page.
Manipuler les arguments d'URL
-----------------------------
Dans cette partie, on cherche à détecter les numéros passés dans l'URL pour les passer dans le template. On commence par ajouter cet URL modifiée.
.. code-block:: python
# hello/urls.py
from django.conf.urls import url
from hello.views import HelloView
urlpatterns = [
url(r"^$", HelloView.as_view(), name="hello"),
# On utilise un regex pour matcher un numéro
url(r"^(?P<hello_id>[0-9]+)$", HelloView.as_view(), name="hello"),
]
Cette deuxième URL vas donc appeler la classe crée tout à l'heure en lui passant une variable *hello_id* dans ses *kwargs*, nous allons la récupérer et la passer dans le contexte du template en allant modifier la vue.
.. code-block:: python
# hello/views.py
from django.views.generic import TemplateView
class HelloView(TemplateView):
template_name = "hello/hello.jinja"
# C'est la méthode appelée juste avant de définir le type de requête effectué
def dispatch(self, request, *args, **kwargs):
# On récupère l'ID et on le met en attribut
self.hello_id = kwargs.pop("hello_id", None)
# On reprend le déroulement normal en appelant la méthode héritée
return super(HelloView, self).dispatch(request, *args, **kwargs)
# Cette méthode renvoie les variables qui seront dans le contexte du template
def get_context_data(self, **kwargs):
# On récupère ce qui était sensé être par défaut dans le contexte
kwargs = super(HelloView, self).get_context_data(**kwargs)
# On ajoute notre ID
kwargs["hello_id"] = self.hello_id
# On renvoie le contexte
return kwargs
Enfin, on modifie le template en rajoutant une petite condition sur la présence ou non de cet ID pour qu'il s'affiche.
.. code-block:: html+jinja
{# hello/templates/hello/hello.jinja #}
{% extends "core/base.jinja" %}
{% block title %}
Hello World
{% endblock title %}
{% block content %}
<p>
Hello World !
{% if hello_id -%}
{{ hello_id }}
{%- endif -%}
</p>
{% endblock content %}
.. note::
Il est tout à fait possible d'utiliser les arguments GET passés dans l'URL. Dans ce cas, il n'est pas obligatoire de modifier l'URL et il est possible de récupérer l'argument dans le dictionnaire `request.GET`.
À l'assaut des modèles
----------------------
Pour cette dernière partie, nous allons ajouter une entrée dans la base de donnée et l'afficher dans un template. Nous allons ainsi créer un modèle nommé *Article* qui contiendra une entrée de texte pour le titre et une autre pour le contenu.
Commençons par le modèle en lui même.
.. code-block:: python
# hello/models.py
from django.db import models
class Article(models.Model):
title = models.CharField("titre", max_length=100)
content = models.TextField("contenu")
Continuons avec une vue qui sera en charge d'afficher l'ensemble des articles présent dans la base.
.. code-block:: python
# hello/views.py
from django.views.generic import ListView
from hello.models import Article
...
# On hérite de ListView pour avoir plusieurs objets
class ArticlesListView(ListView):
model = Article # On base la vue sur le modèle Article
template_name = "hello/articles.jinja"
On n'oublie pas l'URL.
.. code-block:: python
from hello.views import HelloView, ArticlesListView
urlpatterns = [
...
url(r"^articles$", ArticlesListView.as_view(), name="articles_list")
]
Et enfin le template.
.. code-block:: html+jinja
{# hello/templates/hello/articles.jinja #}
{% extends "core/base.jinja" %}
{% block title %}
Hello World Articles
{% endblock title %}
{% block content %}
{# Par défaut une liste d'objets venant de ListView s'appelle object_list #}
{% for article in object_list %}
<h2>{{ article.title }}</h2>
<p>{{ article.content }}</p>
{% endfor %}
{% endblock content %}
Maintenant que toute la logique de récupération et d'affichage est terminée, la page est accessible à l'adresse https://localhost:8000/hello/articles.
Mais, j'ai une erreur ! Il se passe quoi ?! Et bien c'est simple, nous avons crée le modèle mais il n'existe pas dans la base de données. Il est dans un premier temps important de créer un fichier de migrations qui contiens des instructions pour la génération de celle-ci. Ce sont les fichiers qui sont enregistrés dans le dossier migration. Pour les générer à partir des classes de modèles qu'on viens de manipuler il suffit d'une seule commande.
.. code-block:: bash
./manage.py makemigrations
Un fichier *hello/migrations/0001_initial.py* se crée automatiquement, vous pouvez même aller le voir.
.. note::
Il est tout à fait possible de modifier à la main les fichiers de migrations. C'est très intéressant si par exemple il faut appliquer des modifications sur les données d'un modèle existant après cette migration mais c'est bien au delà du sujet de ce tutoriel. Référez vous à la documentation pour ce genre de choses.
J'ai toujours une erreur ! Mais oui, c'est pas fini, faut pas aller trop vite. Maintenant il faut appliquer les modifications à la base de données.
.. code-block:: bash
./manage.py migrate
Et voilà, là il n'y a plus d'erreur. Tout fonctionne et on a une superbe page vide puisque aucun contenu pour cette table n'est dans la base. Nous allons en rajouter. Pour cela nous allons utiliser le fichier *core/management/commands/populate.py* qui contiens la commande qui initialise les données de la base de données de test. C'est un fichier très important qu'on viendra à modifier assez souvent. Nous allons y ajouter quelques articles.
.. code-block:: python
# core/management/commands/populate.py
from hello.models import Article
...
class Command(BaseCommand):
...
def handle(self, *args, **options):
...
Article(title="First hello", content="Bonjour tout le monde").save()
Article(title="Tutorial", content="C'était un super tutoriel").save()
On regénère enfin les données de test en lançant la commande que l'on viens de modifier.
.. code-block:: bash
./manage.py setup
On reviens sur https://localhost:8000/hello/articles et cette fois-ci nos deux articles apparaissent correctement.

191
doc/start/install.rst Normal file
View File

@@ -0,0 +1,191 @@
Installer le projet
===================
Dépendances du système
----------------------
Certaines dépendances sont nécessaires niveau système :
* poetry
* libmysqlclient
* libssl
* libjpeg
* libxapian-dev
* zlib1g-dev
* python
* gettext
* graphviz
* mysql-client (pour migrer de l'ancien site)
Sur Ubuntu
~~~~~~~~~~
.. sourcecode:: bash
sudo apt install libssl-dev libjpeg-dev zlib1g-dev python-dev libffi-dev python-dev libgraphviz-dev pkg-config libxapian-dev gettext git
curl -sSL https://install.python-poetry.org | python -
# To include mysql for importing old bdd
sudo apt install libmysqlclient-dev
Sur MacOS
~~~~~~~~~
Pour installer les dépendances, il est fortement recommandé d'installer le gestionnaire de paquets `homebrew <https://brew.sh/index_fr>`_.
.. sourcecode:: bash
brew install git python xapian graphviz poetry
# Si vous aviez une version de python ne venant pas de homebrew
brew link --overwrite python
# Pour bien configurer gettext
brew link gettext # (suivez bien les instructions supplémentaires affichées)
# Pour installer poetry
pip3 install poetry
.. note::
Si vous rencontrez des erreurs lors de votre configuration, n'hésitez pas à vérifier l'état de votre installation homebrew avec :code:`brew doctor`
Sur Windows avec :code:`WSL`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note::
Comme certaines dépendances sont uniquement disponible dans un environnement Unix, il est obligatoire de passer par :code:`WSL` pour installer le projet.
- **Prérequis:** vous devez exécuter Windows 10 versions 2004 et ultérieures (build 19041 & versions ultérieures) ou Windows 11.
- **Plus d'info:** `docs.microsoft.com <https://docs.microsoft.com/fr-fr/windows/wsl/install>`_
.. sourcecode:: bash
# dans un shell Windows
wsl --install
# afficher la liste des distribution disponible avec WSL
wsl -l -o
# installer WSL avec une distro
wsl --install -d <nom_distro>
.. note::
Si vous rencontrez le code d'erreur ``0x80370102``, regardez les réponses de ce `post <https://askubuntu.com/questions/1264102/wsl-2-wont-run-ubuntu-error-0x80370102>`_.
Une fois :code:`WSL` installé, mettez à jour votre distro & installez les dépendances **(voir la partie installation sous Ubuntu)**.
.. note::
Comme `git` ne fonctionne pas de la même manière entre Windows & Unix, il est nécessaire de cloner le repository depuis Windows.
(cf: `stackoverflow.com <https://stackoverflow.com/questions/62245016/how-to-git-clone-in-wsl>`_)
Pour accéder au contenu d'un répertoire externe à :code:`WSL`, il suffit simplement d'utiliser la commande suivante:
.. sourcecode:: bash
# oui c'est beau, simple et efficace
cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
.. note::
Une fois l'installation des dépendances terminée (juste en dessous), il vous suffira, pour commencer à dev, d'ouvrir votre plus bel IDE et d'avoir 2 consoles:
1 console :code:`WSL` pour lancer le projet & 1 console pour utiliser :code:`git`
Installer le projet
-----------------------------------
.. sourcecode:: bash
# Sait-on jamais
sudo apt update
# Les commandes git doivent se faire depuis le terminal de Windows si on utilise WSL !
git clone https://github.com/ae-utbm/sith3.git
cd Sith
# Création de l'environnement et installation des dépendances
poetry install
# Activation de l'environnement virtuel
poetry shell
# Prépare la base de donnée
python manage.py setup
# Installe les traductions
python manage.py compilemessages
.. note::
Pour éviter d'avoir à utiliser la commande poetry shell systématiquement, il est possible de consulter :ref:`direnv`.
Configuration pour le développement
-----------------------------------
Lorsqu'on souhaite développer pour le site, il est nécessaire de passer le logiciel en mode debug dans les settings_custom. Il est aussi conseillé de définir l'URL du site sur localhost. Voici un script rapide pour le faire.
.. sourcecode:: bash
echo "DEBUG=True" > sith/settings_custom.py
echo 'SITH_URL = "localhost:8000"' >> sith/settings_custom.py
Démarrer le serveur de développement
------------------------------------
Il faut toujours avoir préalablement activé l'environnement virtuel comme fait plus haut et se placer à la racine du projet. Il suffit ensuite d'utiliser cette commande :
.. sourcecode:: bash
python manage.py runserver
.. note::
Le serveur est alors accessible à l'adresse http://localhost:8000.
Générer la documentation
------------------------
La documentation est automatiquement mise en ligne sur readthedocs à chaque envoi de code sur GitLab.
Pour l'utiliser en local ou globalement pour la modifier, il existe une commande du site qui génère la documentation et lance un serveur la rendant accessible à l'adresse http://localhost:8080.
Cette commande génère la documentation à chacune de ses modifications, inutile de relancer le serveur à chaque fois.
.. sourcecode:: bash
python manage.py documentation
# Il est possible de spécifier un port et une adresse d'écoute différente
python manage.py documentation adresse:port
Lancer les tests
----------------
Pour lancer les tests il suffit d'utiliser la commande intégrée à django.
.. code-block:: bash
# Lancer tous les tests
python manage.py test
# Lancer les tests de l'application core
python manage.py test core
# Lancer les tests de la classe UserRegistrationTest de core
python manage.py test core.tests.UserRegistrationTest
# Lancer une méthode en particulier de cette même classe
python manage.py test core.tests.UserRegistrationTest.test_register_user_form_ok
Vérifier les dépendances Javascript
-----------------------------------
Une commande a été écrite pour vérifier les éventuelles mises à jour à faire sur les librairies Javascript utilisées.
N'oubliez pas de mettre à jour à la fois le fichier de la librairie, mais également sa version dans `sith/settings.py`.
.. code-block:: bash
# Vérifier les mises à jour
python manage.py check_front

2
doc/start/mvt_circle.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

2
doc/start/mvt_flat.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

153
doc/start/structure.rst Normal file
View File

@@ -0,0 +1,153 @@
La structure du projet
======================
Le principe MVT
---------------
Django est un framework suivant le modèle MVT (Model-View-Template) aussi appelé MTV (Model-Template-View).
.. figure:: mvt_circle.svg
:alt: Diagramme MVT
:align: center
Diagramme MVT
On peut ainsi voir que la Vue gère la logique d'application, le modèle gère la structure de la base de données et communique avec elle et la vue effectue la logique de l'application. Décris comme ça, cela fait penser au modèle MVC (Model-View-Controller) mais évitons de nous complexifier les choses. Disons que c'est assez proche mais qu'il y a quelques différences (déjà au niveau du nommage).
On peut également représenter le tout sous une autre forme, plus simple à comprendre et visualiser en aplatissant le diagramme. Cela représente mieux ce qui se passe.
.. figure:: mvt_flat.svg
:alt: Diagramme MVT aplati
:align: center
Diagramme MVT aplati
Cette représentation permet de se représenter les interactions sous formes de couches. Avec ça en tête, ce sera plus simple dappréhender la manière dont est découpé le projet.
Le découpage en applications
----------------------------
| /projet
| **sith/**
| Application principale du projet.
| **accounting/**
| Ajoute un système de comptabilité.
| **api/**
| Application où mettre les endpoints publiques d'API.
| **club/**
| Contiens les modèles liés aux clubs associatifs et ajoute leur gestion.
| **com/**
| Fournis des outils de communications aux clubs (weekmail, affiches…).
| **core/**
| Application la plus importante. Contiens les principales surcouches
| liées au projet comme la gestion des droits et les templates de base.
| **counter/**
| Ajoute des comptoirs de vente pour les clubs et gère les ventes sur les lieux de vie.
| **data/**
| Contiens les fichiers statiques ajoutées par les utilisateurs.
| N'est pas suivit par Git.
| **doc/**
| Contiens la documentation du projet.
| **eboutic/**
| Ajoute le comptoir de vente en ligne. Permet d'acheter en carte bancaire.
| **election/**
| Ajoute un système d'élection permettant d'élire les représentants étudiants.
| **forum/**
| Ajoute un forum de discutions.
| **launderette/**
| Permet la gestion des laveries.
| **locale/**
| Contiens les fichiers de traduction.
| **matmat/**
| Système de recherche de membres.
| **pedagogy/**
| Contiens le guide des UVs.
| **rootplace/**
| Ajoute des outils destinés aux administrateurs.
| **static/**
| Contiens l'ensemble des fichiers statiques ajoutés par les développeurs.
| Ce dossier est généré par le framework, il est surtout utile en production.
| Ce dossier n'es pas suivit par Git.
| **stock/**
| Système de gestion des stocks.
| **subscription/**
| Ajoute la gestion des cotisations des membres.
| **trombi/**
| Permet la génération du trombinoscope des élèves en fin de cursus.
| **.coveragec**
| Configure l'outil permettant de calculer la couverture des tests sur le projet.
| **.gitignore**
| Permet de définir quels fichiers sont suivis ou non par Git.
| **.gitlab-ci.yml**
| Permet de configurer la pipeline automatique de GitLab.
| **.readthedocs.yml**
| Permet de configurer la génération de documentation sur Readthedocs.
| **.db.sqlite3**
| Base de données de développement par défaut. Est automatiquement généré
| lors de la configuration du projet en local. N'est pas suivis par Git.
| **LICENSE**
| Licence du projet.
| **LICENSE.old**
| Ancienne licence du projet.
| **manage.py**
| Permet de lancer les commandes liées au framework Django.
| **migrate.py**
| Contiens des scripts de migration à exécuter pour importer les données de l'ancien site.
| **README.rst**
| Fichier de README. À lire pour avoir des informations sur le projet.
| **requirements.txt**
| Contiens les dépendances Python du projet.
L'application principale
------------------------
| /sith
| **__init__.py**
| Permet de définir le dossier comme un package Python.
| Ce fichier est vide.
| **settings.py**
| Contiens les paramètres par défaut du projet.
| Ce fichier est versionné et fait partie intégrant de celui-ci.
| **settings_curtom.py**
| Contiens les paramètres spécifiques à l'installation courante.
| Ce fichier n'est pas versionné et surcharges les paramètres par défaut.
| **urls.py**
| Contiens les routes d'URLs racines du projet.
| On y inclus les autres fichiers d'URLs et leur namespace.
| **toolbar_debug.py**
| Contiens la configuration de la barre de debug à gauche à destination
| du site de développement.
| **et_keys/**
| Contiens la clef publique du système de paiement E-Transactions.
.. warning::
Ne pas mettre de configuration personnelle ni aucun mot de passe dans **settings.py**. Si il y a besoin de ce genre de chose, il faut le mettre dans **settings_custom.py** qui lui n'est pas versionné.
Le contenu d'une application
----------------------------
| /app1
| **__init__.py**
| Permet de définir le dossier comme un package Python.
| Ce fichier est généralement vide.
| **models.py**
| C'est là que les modèles sont définis. Ces classes définissent
| les tables dans la base de donnée.
| **views.py**
| C'est là où les vues sont définies.
| **admin.py**
| C'est là que l'on déclare quels modèles doivent apparaître
| dans l'interface du module d'administration de Django.
| **tests.py**
| Ce fichier contiens les tests fonctionnels, unitaires
| mais aussi d'intégrations qui sont lancés par la pipeline.
| **urls.py**
| On y défini les URLs de l'application et on les lies aux vues.
| **migrations/**
| Ce dossier sert à stocker les fichiers de migration de la base
| de données générées par la commande *makemigrations*.
| **templates/**
| Ce dossier ci contiens généralement des sous dossiers et sert
| à accueillir les templates. Les sous dossiers servent de namespace.

View File

@@ -0,0 +1,81 @@
.. _translations:
Ajouter une traduction
======================
Le code du site est entièrement écrit en anglais, le texte affiché aux utilisateurs l'est également. La traduction en français se fait ultérieurement avec un fichier de traduction. Voici un petit guide rapide pour apprendre à s'en servir.
Dans le code du logiciel
------------------------
Imaginons que nous souhaitons afficher "Hello" et le traduire en français. Voici comment signaler que ce mot doit être traduit.
Si le mot est dans le code Python :
.. sourcecode:: python
from django.utils.translation import gettext_lazy as _
# ...
help_text=_("Hello")
# ...
Si le mot apparaît dans le template Jinja :
.. sourcecode:: html+jinja
{# ... #}
{% trans %}Hello{% endtrans %}
{# ... #}
Générer le fichier django.po
----------------------------
La traduction se fait en trois étapes. Il faut d'abord générer un fichier de traductions, l'éditer et enfin le compiler au format binaire pour qu'il soit lu par le serveur.
.. sourcecode:: bash
./manage.py makemessages --locale=fr --ignore "env/*" -e py,jinja
Éditer le fichier django.po
---------------------------
.. role:: python(code)
:language: python
.. sourcecode:: python
# locale/fr/LC_MESSAGES/django.po
# ...
msgid "Hello"
msgstr "" # Ligne à modifier
# ...
.. note::
Si les commentaires suivants apparaissent, pensez à les supprimer. Ils peuvent gêner votre traduction.
::
#, fuzzy
#| msgid "Bonjour"
Générer le fichier django.mo
----------------------------
Il s'agit de la dernière étape. Un fichier binaire est généré à partir du fichier django.mo.
.. sourcecode:: bash
./manage.py compilemessages
.. note::
Pensez à redémarrer le serveur si les traductions ne s'affichent pas