Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
AE
Sith
Commits
aa92bc94
Commit
aa92bc94
authored
Jun 19, 2016
by
Skia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update report
parent
12b361be
Pipeline
#37
passed with stage
in 1 minute and 16 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
156 additions
and
34 deletions
+156
-34
doc/TW_Skia/Makefile
doc/TW_Skia/Makefile
+2
-2
doc/TW_Skia/Rapport.tex
doc/TW_Skia/Rapport.tex
+154
-32
No files found.
doc/TW_Skia/Makefile
View file @
aa92bc94
...
...
@@ -4,8 +4,8 @@ all: rapport clean
rapport
:
Rapport.tex
@
echo
"Compiling "
$<
$(CC)
$<
$(CC)
$<
$(CC)
-shell-escape
$<
$(CC)
-shell-escape
$<
clean
:
@
echo
"Cleaning folder"
...
...
doc/TW_Skia/Rapport.tex
View file @
aa92bc94
...
...
@@ -18,7 +18,7 @@
\usepackage
{
fancyhdr
}
%Options: Sonny, Lenny, Glenn, Conny, Rejne, Bjarne, Bjornstrup
\usepackage
[Bjornstrup]
{
fncychap
}
\usepackage
[procnames]
{
listings
}
\usepackage
{
minted
}
\usepackage
[colorlinks=true,linkcolor=black]
{
hyperref
}
\usepackage
{
pdfpages
}
\usepackage
{
titlesec, blindtext, color
}
...
...
@@ -47,29 +47,17 @@
\definecolor
{
darkgreen
}{
RGB
}{
0,130,0
}
\definecolor
{
gray
}{
RGB
}{
100,100,100
}
\lstset
{
language=Python,
basicstyle=
\ttfamily\small
,
morekeywords=
{
True,False
}
,
morestring=[s][
\color
{
darkgreen
}
]
{
r'
}{
'
}
,
morestring=[s][
\color
{
brown
}
]
{
"""
}{
"""
}
,
numbers=left,
numberstyle=
\color
{
gray
}
,
keywordstyle=
\color
{
keywords
}
,
commentstyle=
\color
{
comments
}
,
stringstyle=
\color
{
green
}
,
showstringspaces=false,
}
%inner meta
\title
{
Architecture de Sith: le nouveau site AE
}
\author
{
Skia (Florent JACQUET)
}
\date
{
\today
}
\date
{
Dernière version:
\today
}
\begin{document}
\maketitle
\tableofcontents
\listoffigures
\chapter*
{
Introduction
}
\addcontentsline
{
toc
}{
chapter
}{
Introduction
}
...
...
@@ -89,12 +77,12 @@ l'intégralité des fonctions liées à l'argent, qui sont les plus critiques.
\par
C'est là un des choix les plus important lors d'un tel projet, puisqu'il se fait au début, et qu'il n'est ensuite plus
possible de revenir en arrière. Le PHP vieillissant, et
piègeux
\footnote
{
\url
{
https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
}}
a donc été mis de côté au profit
d'un language plus stable, le Python dans sa version 3.
d'un language plus stable, le
\emph
{
Python
}
dans sa version 3.
\section
{
Python3
}
\label
{
sec:python3
}
\par
Le site étant développé en Python, il est impératif d'avoir un environnement de développement approprié à ce
language. L'outil
\verb
#
virtualenv
#
permet d'installer un environnement Python de manière locale, sans avoir besoin des
\par
Le site étant développé en
\emph
{
Python
}
, il est impératif d'avoir un environnement de développement approprié à ce
language. L'outil
\verb
#
virtualenv
#
permet d'installer un environnement
\emph
{
Python
}
de manière locale, sans avoir besoin des
droits root pour installer des packages. De plus cela permet d'avoir sur sa machine plusieurs environnements différents,
adaptés à chaque projet, avec chacun des versions différentes des même paquets.
\par
La procédure pour installer son
\verb
#
virtualenv
#
est décrite dans le fichier
\verb
#
README
#
situé à la racine du
...
...
@@ -102,20 +90,20 @@ projet.
\section
{
Django
}
\label
{
sec:django
}
\par
Django est un framework web pour Python, apparu en 2005, et fournissant un grand nombre de fonctionnalités pour
\par
\emph
{
Django
}
est un framework web pour
\emph
{
Python
}
, apparu en 2005, et fournissant un grand nombre de fonctionnalités pour
développer un site rapidement et simplement. Cela inclut entre autre un serveur Web, pour les échanges HTTP, un parseur
d'URL, pour le routage des différentes URI du site, un ORM
\footnote
{
Object-Relational Mapper
}
pour la gestion de la base
de donnée, ou encore un moteur de template, pour les rendus HTML.
\par
La version 1.8 de Django a été choisie pour le développement de ce projet, car c'est une version LTS (Long Term
\par
La version 1.8 de
\emph
{
Django
}
a été choisie pour le développement de ce projet, car c'est une version LTS (Long Term
Support), c'est à dire qu'elle restera stable et maintenue plus longtemps que les autres (au moins jusqu'en Avril 2018).
\par
La documentation est disponible à cette addresse:
\url
{
https://docs.djangoproject.com/en/1.8/
}
. Bien que ce rapport
présente dans les grandes lignes le fonctionnement de Django, il n'est pas et ne se veut pas exhaustif, et la
présente dans les grandes lignes le fonctionnement de
\emph
{
Django
}
, il n'est pas et ne se veut pas exhaustif, et la
documentation restera donc toujours la référence à ce sujet.
\subsection
{
Le fichier de management et l'organisation d'un projet
}
\label
{
sub:Le fichier de management et l'organisation d'un projet
}
\par
Lors de la création d'un projet Django, plusieurs fichiers sont créés. Ces fichiers sont essentiels pour le projet,
\par
Lors de la création d'un projet
\emph
{
Django
}
, plusieurs fichiers sont créés. Ces fichiers sont essentiels pour le projet,
mais ne contiennent en général pas de code à proprement parler. Ce n'est pas là qu'on y développe quoi que ce soit.
\subsubsection
{
manage.py
}
...
...
@@ -126,7 +114,7 @@ elles:
\begin{itemize}
\item
\textbf
{
startapp
}
\\
Créer une application
\item
\textbf
{
makemigration
}
\\
\item
\textbf
{
makemigration
s
}
\\
Parser les modèles pour créer les fichiers de migration de la base de donnée
\item
\textbf
{
migrate
}
\\
Appliquer les migrations sur la base de données
...
...
@@ -139,15 +127,62 @@ elles:
\par
Un premier dossier est toujours créé, du nom du projet, et contenant plusieurs fichiers:
\verb
#
settings.py
#
,
\verb
#
urls.py
#
, et
\verb
#
wsgi.py
#
.
\par
\verb
#
settings.py
#
est un fichier
\emph
{
Python
}
servant à définir un grand nombre de constantes paramètrant le
fonctionnement du site. L'avantage par rapport à un fichier de configuration classique est que ce dernier est
executable, et on peut donc y mettre de la logique, afin d'avoir des paramètres dynamiques.
\par
\verb
#
urls.py
#
est le fichier principale contenant les routes du site, c'est à dire les URLs existantes. Il se
charge en général d'inclure les fichiers
\verb
#
urls.py
#
de chaque application afin de garder une architecture modulaire
et simple.
\par
\verb
#
wsgi.py
#
contient quant à lui les paramètres pour la mise en production du site en tant qu'application WSGI
(Web Server Gateway Interface) pour tourner derrière un serveur Web.
\subsection
{
Organisation d'une application
}
\label
{
sub:organisation
_
d
_
une
_
application
}
\par
Lorsque l'on créer une application avec
\verb
#
./manage.py startapp
#
, on obtient une fois de plus un dossier type.
On trouve dans celui-ci un certain nombre de fichiers:
\begin{itemize}
\item
\textbf
{
\_\_
init
\_\_
.py
}
\\
Permet de définir le dossier comme un package
\emph
{
Python
}
. Ce fichier est généralement vide.
\item
\textbf
{
models.py
}
\\
C'est là qu'on définit tous les modèles, c'est à dire toutes les classes qui définissent des tables dans la base
de donnée.
\item
\textbf
{
views.py
}
\\
Les vues y sont définies.
\item
\textbf
{
admin.py
}
\\
C'est là que l'on déclare quels modèles doivent apparaîtrent dans l'interface fournie par le module
d'administration.
\item
\textbf
{
tests.py
}
\\
Ce dernier fichier sert à écrire les tests fonctionnels ou unitaires à l'aide de la librairie de test de
\emph
{
Django
}
.
\item
\textbf
{
migrations
}
\\
Ce dossier sert à stocker les fichiers de migration de la base de donnée générés par
\verb
#
./manage.py makemigrations
#
.
\end{itemize}
\vskip
1em
\par
On rajoute par la suite généralement plusieurs fichiers:
\begin{itemize}
\item
\textbf
{
urls.py
}
\\
Pour y définir toutes les URLs de l'application, et ensuite inclure ce fichier dans le fichier
\verb
#
urls.py
#
global au projet.
\item
\textbf
{
templates
}
\\
Celui-ci est un dossier, et on y remet en général un sous dossier du nom de l'application afin de s'en servir de
namespace pour les templates.
\end{itemize}
\vskip
1em
\par
Dans le cas où un fichier
\emph
{
Python
}
deviendrait trop gros ou trop complexe, il est toujours possible de le diviser en
plusieurs fichiers que l'on met dans un dossier du même nom que ce fichier de départ, et contenant en plus un fichier
\verb
#
__init__.py
#
. De plus, pour faciliter les imports depuis ce dossier, on peut mettre dans
\verb
#
__init__.py
#
la
ligne
\footnote
{
Un exemple est disponible dans l'application core
}
:
\mint
{
python
}
|from .[nom
_
de
_
fichier
_
sans
_
le
_
.py] import *|
\subsection
{
Les modèles avec l'ORM
}
\label
{
sub:les
_
modèles
_
avec
_
l
_
orm
}
\subsubsection
{
Le modèle en lui même
}
\label
{
ssub:Le modèle en lui même
}
\par
Rien ne vaudra un bon exemple pour comprendre comment sont construits les modèles avec Django:
\par
Rien ne vaudra un bon exemple pour comprendre comment sont construits les modèles avec
\emph
{
Django
}
:
\begin{addmargin}
[-7em]
{
0em
}
\begin{
lstlisting
}
\begin{
minted}
{
python
}
class Club(models.Model): # (1)
"""
The Club class, made as a tree to allow nice tidy organization
...
...
@@ -172,7 +207,7 @@ class Club(models.Model): # (1)
default
=
settings.SITH
_
GROUPS
[
'root'
][
'id'
])
#
(
7
)
edit
_
groups
=
models.ManyToManyField
(
Group, related
_
name
=
"editable
_
club", blank
=
True
)
#
(
8
)
view
_
groups
=
models.ManyToManyField
(
Group, related
_
name
=
"viewable
_
club", blank
=
True
)
\end
{
lstlisting
}
\end
{
minted
}
\end
{
addmargin
}
\par
Explications:
\begin
{
description
}
...
...
@@ -183,18 +218,18 @@ class Club(models.Model): # (1)
donnée une fois que
\verb
#.
/
manage.py migrate# a été appliqué.
\item
[(
4
)]
Une
\verb
#ForeignKey#, l'une des relations les plus utilisée.
\verb
#related
_
name# précise le nom qui sert
de retour vers cette classe depuis la classe pointée. Ici, elle est même récursive, puisque l'on pointe vers la
classe que l'on est en train de définir, ce qui donne au final une structure d'arbre.
\item
[(
5
)]
On peut toujours préciser des
\verb
#validators#, afin que le modèle soit contraint, et que Django
classe que l'on est en train de définir, ce qui donne au final une structure d'arbre.
)
r
\item
[(
5
)]
On peut toujours préciser des
\verb
#validators#, afin que le modèle soit contraint, et que
\emph
{
Django
}
maintienne toujours des informations cohérentes dans la base.
\item
[(
6
)]
Un message d'erreur peut être précisé pour expliciter à l'utilisateur les problèmes rencontrés.
\item
[(
7
)]
On utilise ici le champ
\verb
#default# pour préciser une valeur par défaut au modèle, et celui
-
ci est
affecté à une valeur contenue dans les
\verb
#settings# de Django.
affecté à une valeur contenue dans les
\verb
#settings# de
\emph
{
Django
}
.
\item
[(
8
)]
Les
\verb
#ManyToManyField# permettent de générer automatiquement une table intermédiaire de manière
transparente afin d'avoir des relations doubles dans les deux classes mises en jeu.
\item
[
OneToOneField
]
Il n'est pas présent dans ce modèle, mais est très utilisé pour étendre une table avec des
informations supplémentaires sans toucher à la table originale.
\item
[
PRIMARY KEY
]
Les plus observateurs d'entre vous auront remarqué qu'il n'y a pas ici de
\verb
#PRIMARY KEY# de précisé. En
effet, Django s'en occupe automatiquement en rajoutant un champ
\verb
#id# jouant ce rôle. On peut alors y
effet,
\emph
{
Django
}
s'en occupe automatiquement en rajoutant un champ
\verb
#id# jouant ce rôle. On peut alors y
accèder en l'appelant par son nom,
\verb
#id# la plupart du temps, sauf s'il a été personnalisé, ou bien par
l'attribut générique
\verb
#pk#, toujours présent pour désigner la
\verb
#PRIMARY KEY# d'un modèle, quelle qu'elle
soit.
...
...
@@ -204,24 +239,111 @@ class Club(models.Model): # (1)
\label
{
ssub:Les migrations
}
\par
Les migrations sont à lancer à chaque fois que l'on modifie un modèle. Elles permettent de conserver la base de
donnée tout en la faisant évoluer dans sa structure, pour ajouter ou supprimer une colonne dans une table par exemple.
\par
Lancer la commande
\verb
#.
/
manage.py makemigration
[
nom de l'appli
]
# va permettre de générer un fichier Python
\par
Lancer la commande
\verb
#.
/
manage.py makemigration
s
[
nom de l'appli
]
# va permettre de générer un fichier
\emph
{
Python
}
automatiquement, qui sera mis à la suite des précédents, et qui sera appliqué sur la base au moment du lancement de
\verb
#.
/
manage.py migrate#.
\subsection
{
Les vues
}
\label
{
sub:les
_
vues
}
\par
Les vues sont les parties de code s'occupant de l'interface avec l'utilisateur. Elles sont appelées par les URLs,
et renvoient des réponses HTTP en fonction du traitement effectué.
\subsubsection
{
Les URL
}
\label
{
ssub:Les URL
}
\par
Les URLs sont définies par application, et centralisées dans le dossier du projet. Il s'agit à chaque fois d'une
liste d'appel à la fonction
\verb
#url
()
#, qui comprends toujours une expression rationnelle décrivant l'URL, une
fonction passée en tant que callback qui sera appelé au moment où l'URL est résolue, et enfin un nom, permettant de s'y
référer dans les fonctiones de résolution inverse, comme dans les templates par exemple. Nous détaillerons cette
utilisation plus tard.
\par
Pour garder une organisation claire, les URLs sont classées par espaces de noms
(
namespace
)
afin d'avoir à éviter
de préfixer tous les noms pour s'y retrouver. Le namespace d'une URL est généralement le même nom que celui de
l'application dans laquelle elle se trouve.
\subsubsection
{
Les fonctions de vue
}
\label
{
ssub:Les fonctions de vue
}
\par
Une fonction de vue prend toujours en paramètre une variable
\verb
#request# et renvoie toujours un objet
\verb
#HTTPResponse#, contenant un code de retour HTTP, ainsi qu'une chaîne de caractères contenant la réponse en elle
même.
\par
Entre temps, le traitement des informations permet de mettre à jour, de créer, ou de supprimer les objets définis
dans les modèles, par le biais des paramètres passé dans la requête. Ainsi, on peut accèder aux informations des
variables
\verb
#GET# et
\verb
#POST# très facilement en appelant respectivement
\verb
#request.GET
[
'ma
_
clef'
]
# et
\verb
#request.POST
[
'ma
_
clef'
]
#, ces deux variables fonctionnant comme des dictionnaires.
\subsubsection
{
Des vues basées sur des classes
}
\label
{
ssub:Des vues basées sur des classes
}
\par
Les vues en
\emph
{
Django
}
peuvent aussi être définies comme des classes. Elles héritent alors à ce moment là toutes de la
classe
\verb
#View#, mais ont toutefois souvent beaucoup d'intermédiaire et n'héritent donc pas directement de cette
dernière.
\par
L'avantage de ces vues sous forme de classe est de pouvoir séparer toute la chaîne de traitement entre les
différentes méthodes, et ainsi permettre, en jouant avec l'héritage, de fournir alors très peu d'informations à la
classe, tout en lui permettant d'effectuer un travail correct.
\par
Ainsi, on retrouve de base, dans les filles de
\verb
#View#, un grand nombre de classes prédéfinies pour la plupart
des comportement.
\verb
#DetailView#,
\verb
#CreateView#,
\verb
#ListView#, sont quelques exemples de classes affichant
respectivement un objet en détails, un formulaire pour créer un nouvel objet, et enfin une liste d'objets. Il existe
cependant un bon nombre de ces vues fournissant d'autres fonctionnalités, et si malgré tout, aucune ne peut convenir, il
reste possible de se baser sur l'une d'elle et surcharger l'une de ses fonctions pour l'adapter à ses besoins.
\par
L'écosystème des
\verb
#class
-
based views# étant toutefois assez complexe et riche, un site web a été créé afin
d'offrir un bon résumé de la situation:
\emph
{
Classy class
-
based views
}
, accessible à l'adresse
\url
{
http:
//
ccbv.co.uk
/
}
.
\section
{
Jinja
2
}
\label
{
sec:jinja
2
}
\par
\emph
{
Jinja
2
}
est un moteur de template écrit en
\emph
{
Python
}
qui s'inspire fortement de la syntaxe des templates de
\emph
{
Django
}
, mais qui apporte toutefois sont lot d'améliorations non négligeable. En effet, l'ajout des macros, par
exemple, permet de factoriser une grande partie du code.
\par
Un moteur de template permet de générer du contenu textuel de manière procédural en fonction des données à
afficher. Cela permet en pratique de pouvoir inclure du code proche de
\emph
{
Python
}
dans la syntaxe au milieu d'un
document contenant principalement du HTML. Ainsi, si on a une liste d'objet, on peut facilement executer une boucle
\verb
#for# afin de faire afficher simplement tous les objets selon le même format.
\noindent
De même, il est facile d'inclure un
\verb
#if# pour décider à l'execution d'afficher ou non un lien en fonction
des droits que l'utilisateur possède sur le site.
\par
En plus des structures conditionnelles classiques, un moteur de templates permet de formater des données plus
simplement, comme par exemple des dates, en fonction de la langue actuellement utilisée par l'utilisateur.
\par
Enfin, bien utilisés, les templates permettent d'utiliser des fonctions d'inclusion, ce qui permet de hiérarchiser
les fichiers, et de s'assurer de l'unité de certaines parties du site. Ainsi, les
\emph
{
headers
}
, les
\emph
{
footers
}
, et
autres menus que l'on retrouve sur toutes les pages du site sont définis chacun dans un seul fichier et inclus dans
tous les autres.
\subsection
{
Exemple de template Jinja
2
}
\label
{
sub:exemple
_
de
_
template
_
jinja
2
}
\begin
{
addmargin
}
[-
7
em
]
{
0
em
}
\begin
{
minted
}{
jinja
}
{
% extends "core/base.jinja" %}
{
% block title %}
{{
user.get
_
display
_
name
()
}}
's tools
{
% endblock %}
{
% block content %}
<h
3
>User Tools<
/
h
3
>
<p><a href
=
"
{{
url
(
'core:user
_
profile', user
_
id
=
request.user.id
)
}}
">Back to profile<
/
a><
/
p>
<h
4
>Sith management<
/
h
4
>
<ul>
{
% if user.is_in_group(settings.SITH_GROUPS['root']['name']) %}
<li><a href
=
"
{{
url
(
'core:group
_
list'
)
}}
">Groups<
/
a><
/
li>
{
% endif %}
{
% if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']) %}
<li><a href
=
"
{{
url
(
'accounting:bank
_
list'
)
}}
">Accounting<
/
a><
/
li>
{
% endif %}
{
% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or user.is_in_group(settings.SITH_GROUPS['root']['name']) %}
<li><a href
=
"
{{
url
(
'subscription:subscription'
)
}}
">Subscriptions<
/
a><
/
li>
<li><a href
=
"
{{
url
(
'counter:admin
_
list'
)
}}
">Counters management<
/
a><
/
li>
{
% endif %}
<
/
ul>
<h
4
>Clubs<
/
h
4
>
<ul>
{
% for m in user.membership.filter(end_date=None).all() %}
<li><a href
=
"
{{
url
(
'club:tools', club
_
id
=
m.club.id
)
}}
">
{{
m.club
}}
<
/
a><
/
li>
{
% endfor %}
<
/
ul>
{
% endblock %}
\end
{
minted
}
\end
{
addmargin
}
% TODO: bases des templates Jinja2
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment