Sith/explanation/technos/index.html

3516 lines
77 KiB
HTML

<!doctype html>
<html lang="fr" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Le site de l'association des étudiants de l'UTBM">
<link rel="canonical" href="https://ae-utbm.github.io/sith/explanation/technos/">
<link rel="prev" href="../">
<link rel="next" href="../conventions/">
<link rel="icon" href="../../img/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.40">
<title>Technologies utilisées - Site AE UTBM</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.8c3ca2c6.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/_mkdocstrings.css">
<link rel="stylesheet" href="../../stylesheets/extra.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="deeppurple" data-md-color-accent="deeppurple">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#backend" class="md-skip">
Aller au contenu
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="En-tête">
<a href="../.." title="Site AE UTBM" class="md-header__button md-logo" aria-label="Site AE UTBM" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Site AE UTBM
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Technologies utilisées
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="deeppurple" data-md-color-accent="deeppurple" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="blue" data-md-color-accent="blue" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6m0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4M7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Rechercher" placeholder="Rechercher" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Recherche">
<button type="reset" class="md-search__icon md-icon" title="Effacer" aria-label="Effacer" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initialisation de la recherche
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/ae-utbm/sith" title="Aller au dépôt" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
sith
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Site AE UTBM" class="md-nav__button md-logo" aria-label="Site AE UTBM" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Site AE UTBM
</label>
<div class="md-nav__source">
<a href="https://github.com/ae-utbm/sith" title="Aller au dépôt" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
sith
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Accueil
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Explications
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Explications
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" class="md-nav__link">
<span class="md-ellipsis">
Accueil
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Technologies utilisées
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Technologies utilisées
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table des matières">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table des matières
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#backend" class="md-nav__link">
<span class="md-ellipsis">
Backend
</span>
</a>
<nav class="md-nav" aria-label="Backend">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-3" class="md-nav__link">
<span class="md-ellipsis">
Python 3
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#django" class="md-nav__link">
<span class="md-ellipsis">
Django
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#postgresql-sqlite3" class="md-nav__link">
<span class="md-ellipsis">
PostgreSQL / SQLite3
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#frontend" class="md-nav__link">
<span class="md-ellipsis">
Frontend
</span>
</a>
<nav class="md-nav" aria-label="Frontend">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#jinja2" class="md-nav__link">
<span class="md-ellipsis">
Jinja2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#jquery" class="md-nav__link">
<span class="md-ellipsis">
jQuery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#alpinejs" class="md-nav__link">
<span class="md-ellipsis">
AlpineJS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sass" class="md-nav__link">
<span class="md-ellipsis">
Sass
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fontawesome" class="md-nav__link">
<span class="md-ellipsis">
Fontawesome
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#workflow" class="md-nav__link">
<span class="md-ellipsis">
Workflow
</span>
</a>
<nav class="md-nav" aria-label="Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#git" class="md-nav__link">
<span class="md-ellipsis">
Git
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#github" class="md-nav__link">
<span class="md-ellipsis">
GitHub
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sentry" class="md-nav__link">
<span class="md-ellipsis">
Sentry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#poetry" class="md-nav__link">
<span class="md-ellipsis">
Poetry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ruff" class="md-nav__link">
<span class="md-ellipsis">
Ruff
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#biome" class="md-nav__link">
<span class="md-ellipsis">
Biome
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#djhtml" class="md-nav__link">
<span class="md-ellipsis">
DjHTML
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#npm" class="md-nav__link">
<span class="md-ellipsis">
Npm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#webpack" class="md-nav__link">
<span class="md-ellipsis">
Webpack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#babel" class="md-nav__link">
<span class="md-ellipsis">
Babel
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../conventions/" class="md-nav__link">
<span class="md-ellipsis">
Conventions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../archives/" class="md-nav__link">
<span class="md-ellipsis">
Archives
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Tutoriels
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Tutoriels
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../tutorial/install/" class="md-nav__link">
<span class="md-ellipsis">
Installer le projet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/install-advanced/" class="md-nav__link">
<span class="md-ellipsis">
Installer le projet (avancé)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/devtools/" class="md-nav__link">
<span class="md-ellipsis">
Configurer son éditeur
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/structure/" class="md-nav__link">
<span class="md-ellipsis">
Structure du projet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/perms/" class="md-nav__link">
<span class="md-ellipsis">
Gestion des permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/groups/" class="md-nav__link">
<span class="md-ellipsis">
Gestion des groupes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../tutorial/etransaction/" class="md-nav__link">
<span class="md-ellipsis">
Etransactions
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
How-to
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
How-to
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../howto/querysets/" class="md-nav__link">
<span class="md-ellipsis">
L'ORM de Django
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/migrations/" class="md-nav__link">
<span class="md-ellipsis">
Gérer les migrations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/translation/" class="md-nav__link">
<span class="md-ellipsis">
Gérer les traductions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/statics/" class="md-nav__link">
<span class="md-ellipsis">
Gérer les statics
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/js-import-paths/" class="md-nav__link">
<span class="md-ellipsis">
Ajouter un chemin d'import javascript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/prod/" class="md-nav__link">
<span class="md-ellipsis">
Configurer pour la production
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/logo/" class="md-nav__link">
<span class="md-ellipsis">
Ajouter un logo de promo
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/subscriptions/" class="md-nav__link">
<span class="md-ellipsis">
Ajouter une cotisation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/weekmail/" class="md-nav__link">
<span class="md-ellipsis">
Modifier le weekmail
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/terminal/" class="md-nav__link">
<span class="md-ellipsis">
Terminal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../howto/direnv/" class="md-nav__link">
<span class="md-ellipsis">
Direnv
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_1" >
<label class="md-nav__link" for="__nav_5_1" id="__nav_5_1_label" tabindex="0">
<span class="md-ellipsis">
accounting
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_1">
<span class="md-nav__icon md-icon"></span>
accounting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/accounting/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/accounting/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_2" >
<label class="md-nav__link" for="__nav_5_2" id="__nav_5_2_label" tabindex="0">
<span class="md-ellipsis">
antispam
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_2">
<span class="md-nav__icon md-icon"></span>
antispam
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/antispam/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/antispam/forms/" class="md-nav__link">
<span class="md-ellipsis">
Forms
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" >
<label class="md-nav__link" for="__nav_5_3" id="__nav_5_3_label" tabindex="0">
<span class="md-ellipsis">
club
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
club
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/club/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/club/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_4" >
<label class="md-nav__link" for="__nav_5_4" id="__nav_5_4_label" tabindex="0">
<span class="md-ellipsis">
com
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_4">
<span class="md-nav__icon md-icon"></span>
com
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/com/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/com/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_5" >
<label class="md-nav__link" for="__nav_5_5" id="__nav_5_5_label" tabindex="0">
<span class="md-ellipsis">
core
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_5">
<span class="md-nav__icon md-icon"></span>
core
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/core/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/core/model_fields/" class="md-nav__link">
<span class="md-ellipsis">
Champs de modèle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/core/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/core/schemas/" class="md-nav__link">
<span class="md-ellipsis">
Schemas
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/core/api_permissions/" class="md-nav__link">
<span class="md-ellipsis">
Api permissions
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_6" >
<label class="md-nav__link" for="__nav_5_6" id="__nav_5_6_label" tabindex="0">
<span class="md-ellipsis">
counter
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_6">
<span class="md-nav__icon md-icon"></span>
counter
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/counter/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/counter/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/counter/schemas/" class="md-nav__link">
<span class="md-ellipsis">
Schemas
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_7" >
<label class="md-nav__link" for="__nav_5_7" id="__nav_5_7_label" tabindex="0">
<span class="md-ellipsis">
eboutic
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_7">
<span class="md-nav__icon md-icon"></span>
eboutic
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/eboutic/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/eboutic/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_8" >
<label class="md-nav__link" for="__nav_5_8" id="__nav_5_8_label" tabindex="0">
<span class="md-ellipsis">
election
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_8">
<span class="md-nav__icon md-icon"></span>
election
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/election/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/election/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_9" >
<label class="md-nav__link" for="__nav_5_9" id="__nav_5_9_label" tabindex="0">
<span class="md-ellipsis">
forum
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_9">
<span class="md-nav__icon md-icon"></span>
forum
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/forum/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/forum/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_10" >
<label class="md-nav__link" for="__nav_5_10" id="__nav_5_10_label" tabindex="0">
<span class="md-ellipsis">
galaxy
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_10">
<span class="md-nav__icon md-icon"></span>
galaxy
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/galaxy/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/galaxy/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_11" >
<label class="md-nav__link" for="__nav_5_11" id="__nav_5_11_label" tabindex="0">
<span class="md-ellipsis">
launderette
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_11">
<span class="md-nav__icon md-icon"></span>
launderette
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/launderette/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/launderette/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_12" >
<label class="md-nav__link" for="__nav_5_12" id="__nav_5_12_label" tabindex="0">
<span class="md-ellipsis">
matmat
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_12">
<span class="md-nav__icon md-icon"></span>
matmat
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/matmat/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/matmat/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_13" >
<label class="md-nav__link" for="__nav_5_13" id="__nav_5_13_label" tabindex="0">
<span class="md-ellipsis">
pedagogy
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_13">
<span class="md-nav__icon md-icon"></span>
pedagogy
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/pedagogy/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/pedagogy/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/pedagogy/schemas/" class="md-nav__link">
<span class="md-ellipsis">
Schemas
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_14" >
<label class="md-nav__link" for="__nav_5_14" id="__nav_5_14_label" tabindex="0">
<span class="md-ellipsis">
rootplace
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_14_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_14">
<span class="md-nav__icon md-icon"></span>
rootplace
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/rootplace/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/rootplace/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_15" >
<label class="md-nav__link" for="__nav_5_15" id="__nav_5_15_label" tabindex="0">
<span class="md-ellipsis">
sas
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_15_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_15">
<span class="md-nav__icon md-icon"></span>
sas
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/sas/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/sas/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/sas/schemas/" class="md-nav__link">
<span class="md-ellipsis">
Schemas
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_16" >
<label class="md-nav__link" for="__nav_5_16" id="__nav_5_16_label" tabindex="0">
<span class="md-ellipsis">
staticfiles
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_16_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_16">
<span class="md-nav__icon md-icon"></span>
staticfiles
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/staticfiles/apps/" class="md-nav__link">
<span class="md-ellipsis">
Apps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/staticfiles/storage/" class="md-nav__link">
<span class="md-ellipsis">
Storage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/staticfiles/finders/" class="md-nav__link">
<span class="md-ellipsis">
Finders
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/staticfiles/processors/" class="md-nav__link">
<span class="md-ellipsis">
Processors
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_17" >
<label class="md-nav__link" for="__nav_5_17" id="__nav_5_17_label" tabindex="0">
<span class="md-ellipsis">
subscription
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_17_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_17">
<span class="md-nav__icon md-icon"></span>
subscription
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/subscription/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/subscription/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_18" >
<label class="md-nav__link" for="__nav_5_18" id="__nav_5_18_label" tabindex="0">
<span class="md-ellipsis">
trombi
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_18_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_18">
<span class="md-nav__icon md-icon"></span>
trombi
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/trombi/models/" class="md-nav__link">
<span class="md-ellipsis">
Models
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/trombi/views/" class="md-nav__link">
<span class="md-ellipsis">
Views
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table des matières">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table des matières
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#backend" class="md-nav__link">
<span class="md-ellipsis">
Backend
</span>
</a>
<nav class="md-nav" aria-label="Backend">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-3" class="md-nav__link">
<span class="md-ellipsis">
Python 3
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#django" class="md-nav__link">
<span class="md-ellipsis">
Django
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#postgresql-sqlite3" class="md-nav__link">
<span class="md-ellipsis">
PostgreSQL / SQLite3
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#frontend" class="md-nav__link">
<span class="md-ellipsis">
Frontend
</span>
</a>
<nav class="md-nav" aria-label="Frontend">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#jinja2" class="md-nav__link">
<span class="md-ellipsis">
Jinja2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#jquery" class="md-nav__link">
<span class="md-ellipsis">
jQuery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#alpinejs" class="md-nav__link">
<span class="md-ellipsis">
AlpineJS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sass" class="md-nav__link">
<span class="md-ellipsis">
Sass
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fontawesome" class="md-nav__link">
<span class="md-ellipsis">
Fontawesome
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#workflow" class="md-nav__link">
<span class="md-ellipsis">
Workflow
</span>
</a>
<nav class="md-nav" aria-label="Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#git" class="md-nav__link">
<span class="md-ellipsis">
Git
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#github" class="md-nav__link">
<span class="md-ellipsis">
GitHub
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sentry" class="md-nav__link">
<span class="md-ellipsis">
Sentry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#poetry" class="md-nav__link">
<span class="md-ellipsis">
Poetry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ruff" class="md-nav__link">
<span class="md-ellipsis">
Ruff
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#biome" class="md-nav__link">
<span class="md-ellipsis">
Biome
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#djhtml" class="md-nav__link">
<span class="md-ellipsis">
DjHTML
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#npm" class="md-nav__link">
<span class="md-ellipsis">
Npm
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#webpack" class="md-nav__link">
<span class="md-ellipsis">
Webpack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#babel" class="md-nav__link">
<span class="md-ellipsis">
Babel
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1>Technologies utilisées</h1>
<p>Bien choisir ses technologies est crucial
puisqu'une fois que le projet est suffisamment avancé,
il est très difficile voir impossible de revenir en arrière.</p>
<p>En novembre 2015, plusieurs choix se présentaient :</p>
<ul>
<li>Continuer avec du PHP</li>
<li>S'orienter vers un langage web
plus moderne et à la mode comme le Python ou le Ruby</li>
<li>Baser le site sur un framework Javascript</li>
</ul>
<p>Le PHP 5, bientôt 7, de l'époque
étant assez discutable comme
<a href="https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/">cet article le montre</a>,
et l'ancien site ayant laissé un goût amer
à certains développeurs, celui-ci a été mis de côté.</p>
<p>L'écosystème Javascript étant à peine naissant
et les frameworks allant et venant en seulement quelques mois,
il était impossible de prédire avec certitude
si ceux-ci passeraient l'épreuve du temps,
il était inconcevable de tout parier là-dessus.</p>
<p>Ne restait plus que le Python et le Ruby
avec les frameworks Django et Ruby On Rails.
Ruby ayant une réputation d'être très "cutting edge",
c'est Python, un langage bien implanté
et ayant fait ses preuves, qui a été retenu.</p>
<p>Il est à noter que réécrire le site avec un framework PHP
comme Laravel ou Symphony eut aussi été possible,
ces deux technologies étant assez matures et robustes
au moment où le développement a commencé.
Cependant, il aurait été potentiellement
fastidieux de maintenir en parallèle deux
versions de PHP sur le serveur durant toute
la durée du développement.
Il faut aussi prendre en compte que nous étions
à ce moment dégoûtés du PHP.</p>
<h2 id="backend">Backend<a class="headerlink" href="#backend" title="Permanent link">&para;</a></h2>
<h3 id="python-3">Python 3<a class="headerlink" href="#python-3" title="Permanent link">&para;</a></h3>
<p><a href="https://www.python.org/">Site officiel</a></p>
<p>Le python est un langage de programmation
interprété multi paradigme sorti en 1991.
Il est très populaire dans de nombreux domaines
pour sa simplicité d'utilisation,
sa polyvalence, sa sécurité ainsi
que sa grande communauté de développeur.
Sa version 3, non rétro compatible avec sa version 2,
a été publiée en 2008.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Puisque toutes les dépendances du backend sont
des packages Python,
elles sont toutes ajoutées directement
dans le fichier <strong>pyproject.toml</strong>,
à la racine du projet.</p>
</div>
<h3 id="django">Django<a class="headerlink" href="#django" title="Permanent link">&para;</a></h3>
<p><a href="https://www.djangoproject.com/">Site officiel</a></p>
<p><a href="https://docs.djangoproject.com/en/latest/">Documentation</a></p>
<p>Django est un framework web pour Python apparu en 2005.
Il fournit un grand nombre de fonctionnalités
pour développer un site rapidement et simplement.
Cela inclut entre autre un serveur Web de développement,
un parseur d'URLs pour le routage,
un ORM (Object-Relational Mapper)
pour la gestion de la base de donnée,
un cadre pour l'écriture et l'exécution des tests,
de nombreux utilitaires pour l'internationalisation,
les zones horaires et autres,
une interface web d'administration aisément configurable,
un moteur de templates pour le rendu HTML...</p>
<p>Django propose une version LTS (Long Term Support)
qui reste stable et est maintenu sur des cycles plus longs.
Ce sont ces versions qui sont utilisées.</p>
<h3 id="postgresql-sqlite3">PostgreSQL / SQLite3<a class="headerlink" href="#postgresql-sqlite3" title="Permanent link">&para;</a></h3>
<p><a href="https://www.postgresql.org/">Site officiel PostgreSQL</a></p>
<p><a href="https://www.sqlite.org/index.html&gt;">Site officiel SQLite</a></p>
<p>Comme la majorité des sites internet,
le Sith de l'AE enregistre ses données
dans une base de données.
Nous utilisons une base de donnée relationnelle
puisque c'est la manière typique d'utiliser
Django et c'est ce qu'utilise son ORM.</p>
<p>Le principal à retenir ici est :</p>
<ul>
<li>Sur la version de production, nous utilisons PostgreSQL,
c'est cette version qui doit fonctionner en priorité.
C'est un système de gestion de base de données fiable,
puissant, activement maintenu, et particulièrement
bien supporté par Django.</li>
<li>Sur les versions de développement,
pour faciliter l'installation du projet,
nous utilisons la technologie SQLite3
qui ne requiert aucune installation spécifique
(la librairie <code>sqlite</code> est incluse dans les
librairies par défaut de Python).
Certaines instructions ne sont pas supportées
par cette technologie et il est parfois nécessaire
d'installer PostgreSQL pour le développement
de certaines parties du site
(cependant, ces parties sont rares, et vous pourriez
même ne jamais en rencontrer une).</li>
</ul>
<p>PostgreSQL est-ce avec quoi le site doit fonctionner.
Cependant, pour permettre aux développeurs
de travailler en installant le moins de dépendances
possible sur leur ordinateur,
il est également désirable de chercher la compatibilité
avec SQLite.
Aussi, dans la mesure du possible, nous
cherchons à ce que les interactions avec la base
de données fonctionnent avec l'un comme avec l'autre.</p>
<p>Heureusement, et grâce à l'ORM de Django, cette
double compatibilité est presque toujours possible.</p>
<h2 id="frontend">Frontend<a class="headerlink" href="#frontend" title="Permanent link">&para;</a></h2>
<h3 id="jinja2">Jinja2<a class="headerlink" href="#jinja2" title="Permanent link">&para;</a></h3>
<p><a href="https://jinja.palletsprojects.com/en/latest/">Site officiel</a></p>
<p>Jinja2 est un moteur de template écrit en Python
qui s'inspire fortement de la syntaxe des templates de Django.
Ce moteur apporte toutefois son lot d'améliorations non négligeables.
Il permet par exemple l'ajout de macros,
sortes de fonctions écrivant du HTML.</p>
<p>Un moteur de templates permet de générer
du contenu textuel de manière procédural
en fonction des données à afficher,
cela permet de pouvoir inclure du code proche du Python
dans la syntaxe au milieu d'un document
contenant principalement du HTML.
On peut facilement faire des boucles ou des conditions
ainsi même que de l'héritage de templates.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>le rendu est fait côté serveur,
si on souhaite faire des modifications côté client,
il faut utiliser du Javascript, rien ne change à ce niveau-là.</p>
</div>
<h3 id="jquery">jQuery<a class="headerlink" href="#jquery" title="Permanent link">&para;</a></h3>
<p><a href="https://jquery.com/">Site officiel</a></p>
<p>jQuery est une bibliothèque JavaScript
libre et multiplateforme créée pour faciliter
l'écriture de scripts côté client
dans le code HTML des pages web.
La première version est lancée en janvier 2006 par John Resig.</p>
<p>C'est une vieille technologie et certains
feront remarquer à juste titre que le Javascript
moderne permet d'utiliser assez simplement
la majorité de ce que fournit jQuery
sans rien avoir à installer.
Cependant, de nombreuses dépendances du projet
utilisent encore jQuery qui est toujours
très implanté aujourd'hui.
Le sucre syntaxique qu'offre cette librairie
reste très agréable à utiliser et économise
parfois beaucoup de temps.
Ça fonctionne et ça fonctionne très bien.
C'est maintenu et pratique.</p>
<h3 id="alpinejs">AlpineJS<a class="headerlink" href="#alpinejs" title="Permanent link">&para;</a></h3>
<p><a href="https://alpinejs.dev/">Site officiel</a></p>
<p>AlpineJS est une librairie légère et minimaliste
permettant le rendu dynamique d'éléments sur une page
web, code de manière déclarative.
La librairie est décrite par ses créateurs comme :
"un outil robuste et minimal pour composer un comportement directement dans vos balises".</p>
<p>Alpine permet d'accomplir la plupart du temps le même résultat qu'un usage des fonctionnalités
de base des plus gros frameworks Javascript,
mais est beaucoup plus léger, un peu plus facile à prendre en main
et ne s'embarrasse pas d'un DOM virtuel.
Grâce à son architecture, il est extrêmement
bien adapté pour un usage dans un site multipage.
C'est une technologie simple et puissante qui se veut comme le jQuery du web moderne.</p>
<h3 id="sass">Sass<a class="headerlink" href="#sass" title="Permanent link">&para;</a></h3>
<p><a href="https://sass-lang.com/">Site officiel</a></p>
<p>Sass (Syntactically Awesome Stylesheets) est un langage dynamique
de génération de feuilles CSS apparu en 2006.
C'est un langage de CSS "amélioré" qui permet
l'ajout de variables
(à une époque où le CSS ne les supportait pas),
de fonctions, mixins ainsi qu'une syntaxe pour
imbriquer plus facilement et proprement les règles
sur certains éléments.
Le Sass est traduit en CSS directement côté serveur
et le client ne reçoit que du CSS.</p>
<p>C'est une technologie stable,
mature et pratique qui ne nécessite pas énormément
d'apprentissage.</p>
<h3 id="fontawesome">Fontawesome<a class="headerlink" href="#fontawesome" title="Permanent link">&para;</a></h3>
<p><a href="https://fontawesome.com&gt;">Site officiel</a></p>
<p>Fontawesome regroupe tout un ensemble
d'icônes libres de droits utilisables facilement
sur n'importe quelle page web.
Ils sont simples à modifier puisque modifiables
via le CSS et présentent l'avantage de fonctionner
sur tous les navigateurs contrairement
à un simple icône unicode qui s'affiche
lui différemment selon la plate-forme.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>C'est une dépendance capricieuse qui évolue très vite
et qu'il faut très souvent mettre à jour.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Il a été décidé de <strong>ne pas utiliser</strong>
de CDN puisque le site ralentissait régulièrement.
Il est préférable de fournir cette dépendance avec le site.</p>
</div>
<h2 id="workflow">Workflow<a class="headerlink" href="#workflow" title="Permanent link">&para;</a></h2>
<h3 id="git">Git<a class="headerlink" href="#git" title="Permanent link">&para;</a></h3>
<p><a href="https://git-scm.com/">Site officiel</a></p>
<p>Git est un logiciel de gestion de versions écrit par
Linus Torvalds pour les besoins du noyau linux en 2005.
C'est ce logiciel qui remplace svn anciennement
utilisé pour gérer les sources du projet
(rappelez vous, l'ancien site date d'avant 2005).
Git est plus complexe à utiliser,
mais est bien plus puissant,
permet de gérer plusieurs versions en parallèle
et génère des codebases vraiment plus légères puisque
seules les modifications sont enregistrées
(contrairement à svn qui garde une copie
de la codebase par version).</p>
<p>Git s'étant imposé comme le principal outil de gestion de versions,
sa communauté est très grande et sa documentation très fournie.
Il est également aisé de trouver des outils avec une interface graphique,
qui simplifient grandement son usage.</p>
<h3 id="github">GitHub<a class="headerlink" href="#github" title="Permanent link">&para;</a></h3>
<p><a href="https://github.com">Site officiel</a></p>
<p><a href="https://github.com/ae-utbm/">Page github du Pôle Informatique de l'AE</a></p>
<p>Github est un service web d'hébergement et de gestion de développement de logiciel.
C'est une plate-forme avec interface web permettant de déposer du code géré avec Git
offrant également de l'intégration continue et du déploiement automatique.
C'est au travers de cette plate-forme que le Sith de l'AE est géré.</p>
<h3 id="sentry">Sentry<a class="headerlink" href="#sentry" title="Permanent link">&para;</a></h3>
<p><a href="https://sentry.io">Site officiel</a></p>
<p><a href="https://ae2.utbm.fr">Instance de l'AE</a></p>
<p>Sentry est une plate-forme libre qui permet
de se tenir informé des bugs qui ont lieu sur le site.
À chaque crash du logiciel (erreur 500),
une erreur est envoyée sur la plate-forme
et il est indiqué précisément à quelle ligne de code
celle-ci a eu lieu, à quelle heure, combien de fois,
avec quel navigateur la page a été visitée et même éventuellement
un commentaire de l'utilisateur qui a rencontré le bug.</p>
<p>C'est un outil incroyablement pratique
pour savoir tout ce qui ne fonctionne pas,
et surtout pour récolter toutes les informations
nécessaires à la réparation des bugs.</p>
<h3 id="poetry">Poetry<a class="headerlink" href="#poetry" title="Permanent link">&para;</a></h3>
<p><a href="https://python-poetry.org/docs/basic-usage/">Utiliser Poetry</a></p>
<p>Poetry est un utilitaire qui permet de créer et gérer
des environnements Python de manière simple et intuitive.
Il permet également de gérer et mettre à jour
le fichier de dépendances.</p>
<p>L'avantage d'utiliser poetry
(et les environnements virtuels en général)
est de pouvoir gérer plusieurs projets différents
en parallèle puisqu'il permet d'avoir sur sa
machine plusieurs environnements différents et
donc plusieurs versions d'une même dépendance
dans plusieurs projets différents sans impacter
le système sur lequel le tout est installé.</p>
<p>Poetry possède également l'avantage par rapport à un simple venv
que les versions exactes de toutes les dépendances,
y compris celles utilisées par d'autres dépendances,
sont consignées dans un fichier <code>.lock</code>.
On est donc sûr et certain que deux environnements virtuels
configurés avec le même fichier lock utiliseront
exactement les mêmes versions des mêmes dépendances,
y compris si celles-ci ne sont pas indiquées explicitement.</p>
<p>Les dépendances utilisées par poetry sont déclarées
dans le fichier <code>pyproject.toml</code>,
situé à la racine du projet.</p>
<h3 id="ruff">Ruff<a class="headerlink" href="#ruff" title="Permanent link">&para;</a></h3>
<p><a href="https://astral.sh/ruff">Site officiel</a></p>
<p>Pour faciliter la lecture du code,
il est toujours appréciable d'avoir
une norme d'écriture cohérente.
C'est généralement à l'étape de relecture
des modifications par les autres contributeurs
que sont repérées ces fautes de normes
qui se doivent d'être corrigées pour le bien commun.</p>
<p>Imposer une norme est très fastidieux,
que ce soit pour ceux qui relisent
ou pour ceux qui écrivent.
C'est pour cela que nous utilisons Ruff,
qui est un formateur et linter automatique de code.
Une fois l'outil lancé, il parcourt la codebase
pour y repérer les fautes de norme et les erreurs de logique courantes
et les corrige automatiquement (quand c'est possible)
sans que l'utilisateur ait à s'en soucier.
Bien installé, il peut effectuer ce travail
à chaque sauvegarde d'un fichier dans son éditeur,
ce qui est très agréable pour travailler.</p>
<h3 id="biome">Biome<a class="headerlink" href="#biome" title="Permanent link">&para;</a></h3>
<p><a href="https://biomejs.dev/">Site officiel</a></p>
<p>Puisque Ruff ne fonctionne malheureusement que pour le Python,
nous utilisons Biome pour le javascript.</p>
<p>Biome est également capable d'analyser et formater les fichiers json et css.</p>
<p>Tout comme Ruff, Biome fait office de formateur et de linter.</p>
<h3 id="djhtml">DjHTML<a class="headerlink" href="#djhtml" title="Permanent link">&para;</a></h3>
<p><a href="https://github.com/rtts/djhtml">Site officiel</a></p>
<p>Ruff permet de formater les fichiers Python et Biome les fichiers js,
mais ils ne formattent pas les templates et les feuilles de style.
Pour ça, il faut un autre outil, aisément intégrable
dans la CI : <code>djHTML</code>.</p>
<p>En utilisant conjointement Ruff, Biome et djHTML,
on arrive donc à la fois à formater les fichiers
Python et les fichiers relatifs au frontend.</p>
<h3 id="npm">Npm<a class="headerlink" href="#npm" title="Permanent link">&para;</a></h3>
<p><a href="https://docs.npmjs.com/cli/v6/commands/npm/">Utiliser npm</a></p>
<p>Npm est un gestionnaire de paquets pour Node.js. C'est l'un des gestionnaires les plus répandus sur le marché et est très complet et utilisé.</p>
<p>Npm possède, tout comme Poetry, la capacité de locker les dépendances au moyen d'un fichier <code>.lock</code>. Il a également l'avantage de presque toujours être facilement disponible à l'installation.</p>
<p>Nous l'utilisons ici pour gérer les dépendances JavaScript. Celle-ci sont déclarées dans le fichier <code>package.json</code> situé à la racine du projet.</p>
<h3 id="webpack">Webpack<a class="headerlink" href="#webpack" title="Permanent link">&para;</a></h3>
<p><a href="https://webpack.js.org/concepts/">Utiliser webpack</a></p>
<p>Webpack est un bundler de fichiers static. Il nous sert ici à mettre à disposition les dépendances frontend gérées par npm.</p>
<p>Il sert également à intégrer les autres outils JavaScript au workflow du Sith de manière transparente.</p>
<p>Webpack a été choisi pour sa versatilité et sa popularité. C'est un des plus anciens bundler et il est là pour rester.</p>
<p>Le logiciel se configure au moyen du fichier <code>webpack.config.js</code> à la racine du projet.</p>
<h3 id="babel">Babel<a class="headerlink" href="#babel" title="Permanent link">&para;</a></h3>
<p><a href="https://babeljs.io/">Babel</a></p>
<p>Babel est un outil qui offre la promesse de convertir le code JavaScript moderne en code JavaScript plus ancien sans action de la part du développeur. Il permet de ne pas se soucier de la compatibilité avec les navigateurs et de coder comme si on était toujours sur la dernière version du langage.</p>
<p>Babel est intégré dans Webpack et tout code bundlé par celui-ci est automatiquement converti.</p>
<p>Le logiciel se configure au moyen du fichier <code>babel.config.json</code> à la racine du projet.</p>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Pied de page" >
<a href="../" class="md-footer__link md-footer__link--prev" aria-label="Précédent: Accueil">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Précédent
</span>
<div class="md-ellipsis">
Accueil
</div>
</div>
</a>
<a href="../conventions/" class="md-footer__link md-footer__link--next" aria-label="Suivant: Conventions">
<div class="md-footer__title">
<span class="md-footer__direction">
Suivant
</span>
<div class="md-ellipsis">
Conventions
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.footer", "content.code.annotate", "content.code.copy", "content.tabs.link"], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copi\u00e9 dans le presse-papier", "clipboard.copy": "Copier dans le presse-papier", "search.result.more.one": "1 de plus sur cette page", "search.result.more.other": "# de plus sur cette page", "search.result.none": "Aucun document trouv\u00e9", "search.result.one": "1 document trouv\u00e9", "search.result.other": "# documents trouv\u00e9s", "search.result.placeholder": "Taper pour d\u00e9marrer la recherche", "search.result.term.missing": "Non trouv\u00e9", "select.version": "S\u00e9lectionner la version"}}</script>
<script src="../../assets/javascripts/bundle.525ec568.min.js"></script>
</body>
</html>