Commit 76343864 authored by Bonnegent Sebastien's avatar Bonnegent Sebastien
Browse files

mise à jour du README de départ

parent 5b1803f6
DEP=$(wildcard *.sty images/*.jpg images/*.png)
THEME=Custom
PDF=evince --presentation
CM=impressive -t Crossfade --nologo
pdf/plan.pdf: plan.md
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR plan.md -o pdf/plan.pdf
plan: pdf/plan.pdf
$(PDF) pdf/plan.pdf
pdf/01.pdf: cours_01.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_01.md -o pdf/01.pdf
html/01.html: cours_01.md $(DEP)
pandoc -t dzslides -s cours_01.md -o html/01.html
1w: html/01.html
cd html && epiphany 01.html
1: pdf/01.pdf
$(PDF) pdf/01.pdf
cm1: pdf/01.pdf
$(CM) pdf/01.pdf
pdf/02.pdf: cours_02.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_02.md -o pdf/02.pdf
2: pdf/02.pdf
$(PDF) pdf/02.pdf
cm2: pdf/02.pdf
$(CM) pdf/02.pdf
pdf/03.pdf: cours_03.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_03.md -o pdf/03.pdf
3: pdf/03.pdf
$(PDF) pdf/03.pdf
cm3: pdf/03.pdf
$(CM) pdf/03.pdf
pdf/04.pdf: cours_04.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_04.md -o pdf/04.pdf
4: pdf/04.pdf
$(PDF) pdf/04.pdf
cm4: pdf/04.pdf
$(CM) pdf/04.pdf
pdf/05.pdf: cours_05.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_05.md -o pdf/05.pdf
5: pdf/05.pdf
$(PDF) pdf/05.pdf
cm5: pdf/05.pdf
$(CM) pdf/05.pdf
pdf/06.pdf: cours_06.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_06.md -o pdf/06.pdf
6: pdf/06.pdf
$(PDF) pdf/06.pdf
cm6: pdf/06.pdf
$(CM) pdf/06.pdf
pdf/07.pdf: cours_07.md $(DEP)
pandoc -st beamer -V theme:$(THEME) -V lang:fr-FR cours_07.md -o pdf/07.pdf
7: pdf/07.pdf
$(PDF) pdf/07.pdf
cm7: pdf/07.pdf
$(CM) pdf/07.pdf
clean:
rm -rf pdf/*.pdf
Objectifs
=========
# Objectifs
Support de cours pour 7 créneaux de 1h30 sur le format 30mn de CM / 1h de TP
par séance.
par séance. Durant ces 7 séances, vous allez créer une application web
de gestion des règles de parefeux.
Installation sur une fedora 27
==============================
## Installation sur une fedora 27
~~~
$ dnf install pandoc pandoc-pdf texlive-latex-bin-bin texlive-beamer \
......@@ -14,13 +13,27 @@ $ git clone git@gitlab.insa-rouen.fr:bonnegent/cours_django.git
~~~
Le répertoire pdf/ contient les présentations et les répertoires cours_XX
contiennent les supports de cours.
# Plan
* mise en place du projet: pipenv
* backend: models, shell, migration
* frontend
- administration, runserver
- urls, templates, vues
- CDN, firefox F12, umatrix
* outils: logs, messages, scripts de gestion
* sécurité: hijack, restriction d'accés
* 'rest' facile
* tests: pytest, black
## Évaluations
Outils utilisés
===============
- 1 QCM pendant la dernière séance
* vim
* pandoc
* https://blog.rom1v.com/2014/02/des-slides-beamer-en-markdown/
# Comment démarrer ?
~~~
$ git clone https://gitlab.insa-rouen.fr/bonnegent/cours_django/
$ cd cours_django
$ git checkout cours_1
~~~
Il faut ouvrir le fichier **cours.html** dans votre navigateur favori.
% the 3 colors
\definecolor{Color1}{HTML}{25567B}
\definecolor{Color2}{HTML}{033E6B}
\definecolor{Color3}{HTML}{66A3D2}
% the logo on the title page
% \titlegraphic{\includegraphics[height=1.5cm]{avatar.png}}
\titlegraphic{\includegraphics[height=1.5cm]{images/logo_django.png}}
% the logo on every page
\logo{\includegraphics[height=0.5cm]{images/logo_insa_rouen.png}}
\usepackage{booktabs,latexsym,amssymb,wasysym}
\hypersetup{colorlinks,linkcolor=,urlcolor=Color3}
\useoutertheme{split}
\usecolortheme{whale}
\usecolortheme{orchid}
\useinnertheme[shadow]{rounded}
% to disable the navigation bar
\setbeamertemplate{navigation symbols}{}
\setbeamercolor{frametitle}{bg=white,fg=Color2}
\setbeamercolor{palette primary}{bg=Color3,fg=white}
\setbeamercolor{palette secondary}{bg=Color2}
\setbeamercolor{palette tertiary}{bg=Color3}
\setbeamercolor{palette quaternary}{bg=Color1}
\setbeamercolor{normal text}{fg=Color1}
\setbeamercolor{block title}{bg=Color2}
\setbeamercolor{example text}{fg=Color3}
\setbeamercolor{alerted text}{fg=Color1}
\setbeamercolor{item}{parent=normal text}
\setbeamercolor{section in toc}{fg=Color3}
% title blocks: can be better depending on selected colors
%\setbeamercolor{titlelike}{bg=Color2,fg=white}
\newcommand{\code}[1]{\textcolor{Color3}{\footnotesize{\texttt{#1}}}}
\newcommand{\entity}[1]{\textcolor{Color2}{#1}}
\newcommand{\good}{\textcolor{green}{\smiley}}
\newcommand{\bad}{\textcolor{red}{\frownie}}
% Does not work when generated from markdown using pandoc
%\AtBeginPart{\frame{\partpage}}
%
%\AtBeginSection[]
%{
% \begin{frame}<beamer>
% \frametitle{Plan}
% \tableofcontents[currentsection]
% \end{frame}
%}
% This is the correct way to get the frame number in the footline,
% by modifying beamerouterthemesplit footline.
\setbeamertemplate{footline}{
\leavevmode
\hbox{\begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,leftskip=.3cm plus1fill,rightskip=.3cm]{author in head/foot}
\usebeamerfont{author in head/foot}\insertshortauthor
\end{beamercolorbox}%
\begin{beamercolorbox}[wd=.5\paperwidth,ht=2.5ex,dp=1.125ex,leftskip=.3cm,rightskip=.3cm plus1fil]{title in head/foot}%
\usebeamerfont{title in head/foot}\insertshorttitle
\usebeamerfont{date in head/foot}
\hfill\insertframenumber{} / \inserttotalframenumber\hspace*{2ex}
\end{beamercolorbox}}
}
% Django par la pratique #01
% Sébastien Bonnegent
% version 2018
# Django
### Définition
> The web framework for perfectionists with deadlines.[^dj]
[^dj]: \tiny https://www.djangoproject.com/
## À propos
### Qu'est ce que c'est ?
- framework python pour applications web
- ORM: couche d'abstraction entre les classes et la BD
- BD supportées: postgresql, mysql, sqlite, oracle, ...
- moteur de templates pour l'affichage (jinla)
## À propos
### Avantages
- gestion des migrations
- rapidité de mise en place
- factorisation du code
- interface d'administration automatique
- modèle MVC
- ...
. . .
### Inconvénients
- ?
## Prérequis
### L'environnement
- pipenv (voir le wiki du projet)
- source /opt/venv/django/bin/activate
### Création
~~~
$ mkdir vehicules
$ cd !$
~~~
## Création du projet
~~~
$ django-admin startproject conf .
~~~
\center\includegraphics[height=2.5cm]{images/tree-conf.png}
## Création d'une application
~~~
$ django-admin startapp garage
~~~
\center\includegraphics[height=2.5cm]{images/tree-garage.png}
## Activation de l'application
### conf/settings.py
~~~python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'garage',
'django_extensions',
]
~~~
## Configuration
### conf/settings.py
~~~python
DEBUG = True
ALLOWED_HOSTS = []
ROOT_URLCONF = 'conf.urls'
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Europe/Paris'
SECRET_KEY = 'Une_clef_secrete_et_longue!'
~~~
. . .
### Si besoin, pour générer une nouvelle clé
~~~
$ ./manage.py generate_secret_key
f#wgrz$@#wh@*x5)_+(*$$^aw(c!q#a4)c0230bwp!iy
~~~
## Pour git
### .gitignore
~~~
*.pyc
conf/settings.py
*/__pycache__
db.sqlite3*
~~~
### Ajout
~~~
$ git add .gitignore
~~~
## Gestion des migrations
### Création des migrations (si nécessaire)
~~~
$ ./manage.py makemigrations
~~~
. . .
### Application des migrations
~~~
$ ./manage.py migrate
~~~
\center\includegraphics[height=3.5cm]{images/tree-migrate-initial.png}
# Notre projet
## Diagramme des classes
\center\includegraphics[height=4cm]{../vehicules/docs/diagramme_des_classes.png}
. . .
Note: pas de clé primaire !
## À vous de jouer !
### Documentation
- https://docs.djangoproject.com/fr/ (couche des modèles)
- fichier à modifier: garage/models.py
- faire la classe Garage
## Lorsque la classe est terminée
### ./manage.py makemigrations
~~~
Migrations for 'garage':
garage/migrations/0001_initial.py
- Create model Garage
~~~
### ./manage.py migrate
~~~
Operations to perform:
Apply all migrations: admin, auth, contenttypes, \
garage, sessions
Running migrations:
Applying garage.0001_initial... OK
~~~
## Fichier de migrations
### garage/migrations/0001_initial.py
~~~python
# [...]
migrations.CreateModel(
name='Garage',
fields=[
('id', models.AutoField(auto_created=True, ...
('nom', models.CharField(max_length=32)),
('adresse', models.CharField(max_length=128, ...
('mail', models.EmailField(max_length=254, ...
('telephone', models.CharField(max_length=12, ...
~~~
### Note
Les fichiers de migrations sont à mettre dans le git !
## Le shell
### Accès au shell
~~~
$ ./manage.py shell
$ # shell avec chargement automatique des classes
$ ./manage.py shell_plus
~~~
. . .
### ./manage.py shell_plus
~~~{.py .numberLines}
>>> # Utiliser la complétion automatique (TAB) !
>>> user = User(username='toto')
>>> user.save()
>>> g = Garage(nom="Mon garage", createur=user)
>>> g.nom
'Mon garage'
>>> g.save()
>>> g
<Garage: Garage object (1)>
~~~
## Affichage des objets
### Modifier l'affichage
~~~{.py .numberLines}
def __str__(self):
return self.nom
~~~
. . .
### Résultat
~~~{.py .numberLines}
>>> Garage.objects.get(nom="Mon garage")
<Garage: Mon garage>
>>> Garage(nom="Autre", createur=user).save()
>>> Garage(nom="Zzz", adresse="25 rue toto", createur=user).save()
>>> Garage.objects.all()
<QuerySet [<Garage: Mon garage>, <Garage: Autre>,
<Garage: Zzz>]>
~~~
## Trier les instances automatiquement
### Modifier l'ordre d'affichage
~~~{.py .numberLines}
class Garage(models.Model):
class Meta(object):
ordering = ("nom", "adresse")
~~~
. . .
### ./manage.py shell_plus
~~~{.py .numberLines}
>>> Garage.objects.all()
<QuerySet [<Garage: Autre>, <Garage: Mon garage>,
<Garage: Zzz>]>
~~~
## Manipulation en shell
### ./manage.py shell_plus
~~~{.py .numberLines}
>>> grg, flag = Garage.objects\
.get_or_create(nom="L'autre fils")
>>> filtre = Garage.objects.filter
>>> filtre(nom__contains="Autre")
>>> filtre(nom__icontains="Autre")
>>> filtre(mail__endswith=".fr")\
.filtre(adresse__contains="Rouen")
~~~
. . .
~~~
>>> Garage.objects.get(nom="Zzz").delete()
>>> Garage.objects.all().delete()
~~~
## À vous de jouer #2
### Faire dans l'ordre les classes
- Vehicule
- AFaire
- Entretien
### Documentation
- https://docs.djangoproject.com/fr/
- fichier à modifier: garage/models.py
% Django par la pratique #02
% Sébastien Bonnegent
% version 2018
# Interface d'administration
## Prérequis
### garage/models.py
- Garage
- Vehicule
- AFaire
- Entretien
### un venv
~~~
$ source /opt/venv/django/bin/activate
$ pipenv run ...
~~~
## Développement
### Lancement du serveur de développement
~~~
$ ./manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
September 28, 2017 - 13:29:48
Django version 1.11, using settings 'conf.settings'
Starting development server at http://127.0.0.1:8000/
~~~
## Consultation
### Adresse
- http://localhost:8000/
- http://localhost:8000/admin/
### Création d'un compte administrateur
~~~
$ ./manage.py createsuperuser
~~~
## Ajout de nos classes
### garage/admin.py
~~~python
from .models import Garage, Vehicule, AFaire, \
Entretien
admin.site.register(Garage)
admin.site.register(Vehicule)
admin.site.register(AFaire)
admin.site.register(Entretien)
~~~
### http://localhost:8000/admin/
- rafraichir l'affichage
- créer des objets dans les différentes classes
## Personnalisation
### garage/admin.py
~~~python
class EntretienAdmin(admin.ModelAdmin):
list_display = ('vehicule', 'kms', 'date', 'montant')
date_hierarchy = 'date'
# ordering = ['date'] >> class Meta
search_fields = ['vehicule__marque',
'vehicule__modele']
admin.site.register(Entretien, EntretienAdmin)
~~~
# MVC
## Modèle Vue Contrôleur (~MTV)
### Modèle
- garage/models.py
- logique métier
- intelligence
. . .
### Vue
- garage/templates
- garage/views.py
. . .
### Contrôleur
- Django
- garage/urls.py
## Définition
### Wikipedia
~~~
https://fr.wikipedia.org/wiki/Modèle-vue-contrôleur
~~~
# 1er page web
## Vue
### garage/views.py
~~~python
from django.http import HttpResponse
def home(request):
"""Page d'accueil"""
return HttpResponse('ça marche !')
~~~
## Routage d'URLs
### conf/urls.py
~~~python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
~~~
. . .
~~~python
path('', include('garage.urls')),
]
~~~
## Routage d'URLs #2
### garage/urls.py
~~~python
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]
~~~
## Frontend (JS mais pas trop)
### Bootstrap
- https://pypi.org/project/django-bootstrap-static/
- https://getbootstrap.com/
### Installation
~~~
$ mkdir -p garage/templates/garage
~~~
### conf/settings.py
~~~python
INSTALLED_APPS = [
# ...
'bootstrap',
'fontawesome',
]
~~~
## garage/templates/garage/home.html
### head (v1)
~~~html
{% load static %}
<!doctype html>
<html lang="fr"><head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1,
shrink-to-fit=no">
<title>Garage</title>
<link rel="stylesheet"
href="{% static 'bootstrap/css/bootstrap.min.css' %}">