Technologies avancées

Transcription

Technologies avancées
Technologies avancées
Olivier Pons / 2016
Technologies avancées
Objectif
Connaître les bases
Django
Olivier Pons / 2015
Technologies avancées
2 – Site basique
1 – Django – Installation
Etapes qui vont suivre
1. Installation de l'environnement
2. Installation de Django
3. Création d'un projet vide
4. Création d'une application ”monblog”
Olivier Pons / 2016
3 / 71
Technologies avancées
2 – Site basique
1 – Django – Installation
Création de l'environnement virtuel
mkdir monenv
cd monenv
python3 -m venv myvenv
myvenv/bin/activate ←→ source bin/activate
myvenv/bin/pip install --upgrade pip
myvenv/bin/pip install django
Olivier Pons / 2016
4 / 71
Technologies avancées
2 – Site basique
1 – Django – Installation
Création de l'environnement virtuel – Python 2.x
mkdir monenv
cd monenv
virtualenv myvenv
source myvenv/bin/activate
myvenv/bin/pip install requests
myvenv/bin/pip install --upgrade pip
myvenv/bin/pip install django
Olivier Pons / 2016
5 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Création du projet
> myvenv/bin/django-admin.py startproject monprojet .
> tree monprojet
monprojet/
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Editez monprojet/settings.py
Et mettez le en français, avec TIMEZONE à ”Europe/Paris”
Olivier Pons / 2016
6 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Les fichiers de base
monprojet/
→ Dossier racine
├── __init__.py → monprojet est un module
├── settings.py → configuration du site Web
├── urls.py
→ résolution des routes (urlresolver)
└── wsgi.py
→ Web Server Gateway Interface = serveur
Olivier Pons / 2016
7 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Création du projet
Le fichier manage.py est
une sorte d'enveloppe de ”django-admin”
L'interface d'administration n'existe pas car…
elle est générée automatiquement !
En attendant il faut demander à générer
la base de données dont se servent les modules
de base…
Puis générer une application.
En général : un projet, qui contient plusieurs applications
Olivier Pons / 2016
8 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Création de la base de données
myvenv/bin/python3 manage.py migrate
Olivier Pons / 2016
9 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Lancement du serveur
myvenv/bin/python3 manage.py runserver
Olivier Pons / 2016
10 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Nouvelle application
>> myvenv/bin/python3 manage.py startapp monblog
>> tree monblog/
monblog/
├── __init__.py
├── admin.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
Olivier Pons / 2016
11 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Nouvelle application
Ajouter dans monprojet/settings.py l'application 'monblog'
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'monblog',
)
Olivier Pons / 2016
12 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Modèle exemple
Mettre dans monblog/models.py :
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
Olivier Pons / 2016
13 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Modèle exemple
>> myvenv/bin/python3 manage.py makemigrations monblog
>> myvenv/bin/python3 manage.py migrate monblog
Olivier Pons / 2016
14 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
QuerySet
>>
>>
>>
>>
>>
>>
>>
>>
>>
myvenv/bin/python3 manage.py shell
from monblog.models import Post
from django.contrib.auth.models import User
User.objects.all()
User.objects.create(username='olivier')
User.objects.all()
User.objects.get(username='olivier')
moi = User.objects.get(username='olivier')
Post.objects.create(
author = moi, title = 'Mon titre',
text = 'Test')
>> Post.objects.filter(author=moi)
Olivier Pons / 2016
15 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
QuerySet
>> post = Post.objects.get(id=1)
>> post.publish()
>> Post.objects.filter(published_date__isnull=False)
>> Post.objects.order_by('created_date')
>> Post.objects.order_by('-created_date')
>> exit
Olivier Pons / 2016
16 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Administration
Créer un superadmin :
myvenv/bin/python3 manage.py createsuperuser
Mettre dans monblog/admin.py :
from django.contrib import admin
from .models import Post
admin.site.register(Post)
Relancer le serveur
myvenv/bin/python3 manage.py runserver
Aller sur : http://127.0.0.1:8000/admin/
Olivier Pons / 2016
17 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Olivier Pons / 2016
18 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Urls
Ajouter l'URL dans monprojet/urls.py :
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'', include('monblog.urls')),
]
Créer le fichier en conséquence : monblog/urls.py
from django.conf.urls import patterns, include, url
from . import views
urlpatterns = patterns('',
url(r'^$', views.post_list),
)
Olivier Pons / 2016
19 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templating
Ajouter l'URL dans monblog/views.py :
from django.shortcuts import render
def post_list(request):
return render(request, 'blog/post_list.html', {})
Créer les dossiers puis le fichier en conséquence :
>>> mkdir monblog/templates
>>> mkdir monblog/templates/blog
>>> vim monblog/templates/blog/post_list.html
Olivier Pons / 2016
20 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Comparaison Python / Php
Olivier Pons / 2016
21 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Comparaison Python / Php
Symfony : générer l'interface d'administration / Sonata
- Installer le bundle
- Rajouter / modifier le routing
- Publier les assets
- Décommenter le traducteur (multilangue)
- Supprimer les routes inutiles
- Générer toutes les classes d'admin.
- Eventuellement, activer cmf_tree (→ 3 actions en plus)
http://symfony.com/doc/current/cmf/tutorial/sonata-admin.html
Django : rien à faire. Si, si. Rien.
Olivier Pons / 2016
22 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données dynamiques
Lancer python ”local” : myvenv/bin/python3
Puis
import os
os.environ['DJANGO_SETTINGS_MODULE']='monprojet.settings'
from django.contrib.auth.models import User
import monblog.models
posts = monblog.models.Post.objects\
.filter(published_date__isnull=False)\
.order_by('published_date')
posts
Olivier Pons / 2016
23 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données dynamiques
Toutes les conditions possibles sont après ”__” :
xxx.filter(nomchamp__lte = xx)
xxx.filter(nomchamp__gt = xx)
xxx.filter(nomchamp__startwith = xx)
xxx.filter(nomchamp__endswith = xx)
xxx.filter(nomchamp__exact = xx)
xxx.filter(nomchamp__iexact = xx)
xxx.filter(nomchamp__contains = xx)
xxx.get(id = xx)
xxx.objects.all()[:5]
Olivier Pons / 2016
24 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données dynamiques
Ajouter dans monblog/views.py :
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects\
.filter(published_date__isnull=False)\
.order_by('published_date')
return render(
request, 'blog/post_list.html', {'posts': posts}
)
Relancer le serveur Web
Olivier Pons / 2016
25 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données dynamiques
Ajouter dans monblog/templates/blog/post_list.html :
{% for post in posts %}
<div>
<p>Publié le&nbsp;: {{ post.published_date }}</p>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
Relancer le serveur Web
Olivier Pons / 2016
26 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données statiques
Créez le dossier ”static” à la racine puis ”css” :
mkdir static
mkdir static/css
Modifiez ”monprojet/settings.py” :
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
Relancer le serveur Web
Olivier Pons / 2016
27 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Données statiques
Modifier première ligne de
”monblog/templates/blog/post_list.html” :
{% load staticfiles %}
Puis dans le <head></head> ajouter :
<link rel="stylesheet" href="{% static "css/blog.css" %}">
Relancer le serveur Web
→ Intégrer totalement un boilerplate au choix (voir après)
Olivier Pons / 2016
28 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Boilerplates
Initializr
99lime
Alsacreation
http://www.initializr.com/
http://www.99lime.com/elements/
http://schnaps.it/
http://fortawesome.github.io/Font-Awesome/cheatsheet/
Olivier Pons / 2016
29 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Templates / Héritage
Fichier base.html contient toute la base
avec des blocs vides :
{% block content %}
{% endblock %}
Les fichiers qui héritent ”remplissent” ces blocs :
”monblog/templates/blog/post_list.html” :
{% block content %}
{% for post in posts %}
…
{% endfor %}
{% endblock content %}
Olivier Pons / 2016
30 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Url + Template + QuerySet
Editer monblog/urls.py y ajouter dans les patterns :
url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail),
Editer ”monblog/views.py” :
from django.shortcuts import render, get_object_or_404
def post_detail(request, pk):
post = get_object_or_404(post, pk=pk)
return render(
request, 'blog/post_detail.html',
{'post': post}
)
Olivier Pons / 2016
31 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Url + Template + QuerySet
Editer ”monblog/templates/blog/post_detail.html” :
{% extends "blog/base.html" %}
{% block content %}
<div class="date">
{% if post.published_date %}
Publié le : {{ post.published_date }}
{% endif %}
</div>
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
{% endblock %}
Olivier Pons / 2016
32 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires – Simples (pas liés à un modèle)
Principe
→ Déclarer une classe dérivée
de ”forms.Form” dans forms.py
→ Déclarer une vue de type ”FormView”
dans views.py
→ Mettre la forme en visuel dans
les templates (xxx.html)
Olivier Pons / 2016
33 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires – Simples (pas liés à un modèle)
forms.py
class RegisterForm(forms.Form):
username = forms.CharField()
prenom = forms.CharField()
etc.
prenom = forms.CharField(
label=u'Entrez votre prénom',
max_length=100)
Ce ne sont que des définitions de champs = ”Fields”
Olivier Pons / 2016
34 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires – Simples (pas liés à un modèle)
views.py
class RegisterView(FormView):
template_name = 'applancement/index.html'
form_class = RegisterForm
def form_valid(self, form):
username = form.cleaned_data['username']
prenom = form.cleaned_data['prenom']
...
return HttpResponseRedirect(u'{0}{1}'.format(
site_web, self.request.META['PATH_INFO']
))
Olivier Pons / 2016
35 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires – Simples (pas liés à un modèle)
templates/index.html
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.label_tag }}<br />{{ field }}<br />
{% if field.errors %}
{{ field.errors }}
{% endif %}
{{ field.help_text }}
{% endfor %}
{{ form.non_field_errors }}
<input type="submit" value="Register!">
</form>
Olivier Pons / 2016
36 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires
Editer ”monblog/forms.py” :
from django import forms
from .models import Post
← formulaires Django
← notre modèle
class PostForm(forms.ModelForm): ← Classe dérivée
← classe où définir :
class Meta:
← - la table
model = Post
fields = ('title', 'text',)← - les champs
Olivier Pons / 2016
37 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Formulaires
Ajouter le lien vers le formulaire :
<a href="{% url "blog.views.post_new" %}"
class="top-menu">
<span class="glyphicon glyphicon-plus"></span>
</a>
Olivier Pons / 2016
38 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Droits
Authentification Vérifie que l’utilisateur
est bien celui qu’il prétend être
Autorisation
Détermine ce qu’un utilisateur
authentifié est autorisé à faire
Installation
Tout est déjà fait (settings.py)
django.contrib.auth
Authentification
django.contrib.contenttypes
Association modèles ↔ permissions
Olivier Pons / 2016
39 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Décorateurs
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET", "POST"])
def my_view(request):
# arrivé ici = que GET ou POST !
pass
→ require_GET(), require_POST(), require_safe()
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def my_view(request):
...
Olivier Pons / 2016
40 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Décorateurs
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote', login_url='/login/')
def my_view(request):
...
Dans l'application polls :
class Poll(models.Model):
def can_vote(self, user):
return not self.vote_set.filter(user=user).exists()
Olivier Pons / 2016
41 / 71
Technologies avancées
2 – Site basique
1 – Django – Blog
Décorateurs
from django.contrib.auth.decorators import user_passes_test
def email_ok(user):
return user.email.endswith('@gmail.com')
@user_passes_test(email_ok)
def my_view(request):
...
Olivier Pons / 2016
42 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
URLs paramétrées
Dans urls.py
urlpatterns = [
....
url(_(r'^vente-groupee/(?P<slug>[a-zA-Z0-9-_]+)/$'),
p_views.DetailView.as_view(), name='vente_groupee'),
....
Dans un fichier de template :
<a href="{% url 'vente_groupee' monparam %}">Ici<a/>
Olivier Pons / 2016
43 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Sessions
Dans settings.py vérifier que MIDDLEWARE_CLASSES contient
django.contrib.sessions.middleware.SessionMiddlewarer
Puis dans les vues :
→ Le premier paramètre d'une vue est un objet HttpRequest
→ Via cet objet, on accède à la propriété session
requestion.session.['id']=654654
exemple = requestion.session.get('id')
del request.session['id']
Fonctions les plus utilisées de session :
keys(), items(), setdefault(), clear(), flush()
https://docs.djangoproject.com/fr/1.8/topics/http/sessions/ 44
Olivier Pons / 2016
/ 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Namespace
Définition du namespace dans la route ”principale”
Ajouter dans urls.py
urlpatterns = [
url(_(r'^monapp/'),
include('monapp.urls', namespace="produits")),
url(r'^admin/', include(admin.site.urls)),
]
Olivier Pons / 2016
45 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Namespace
Définition des routes dans l'application même : blog/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
]
Olivier Pons / 2016
46 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Modèles : choix multiple
from django.db import models
from django.utils.translation import gettext_lazy as _
DIFFICULTY = (('easy', _('Easy')),
('medium', _('Medium')),
('hard', _('Hard')))
class Exercise(models.Model):
name = models.CharField(max_length=300, unique=True)
level = models.CharField(
max_length=15,
choices=DIFFICULTY)
Olivier Pons / 2016
47 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Modèles : base abstraite
class BaseModel(models.Model):
date_creation = models.DateTimeField(
auto_now_add=True
)
date_last_modif = models.DateTimeField(
auto_now=True
)
class Meta:
abstract = True
Olivier Pons / 2016
48 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Modèles : exemple de filtre
https://docs.djangoproject.com/fr/1.8/topics/db/queries/
Dans le modèle :
class Produit(BaseModel):
tags = models.ManyToManyField(
Tag, related_name='produits'
)
Dans la vue :
Tag.objects.filter(
produits__in=Produit.objects.all()
).distinct()
Olivier Pons / 2016
49 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Administration : ManyToMany
class ProduitTagsInline(admin.TabularInline):
model = Produit.tags.through
extra = 0
class ProduitDescriptionsInline(admin.TabularInline):
model = Produit.descriptions.through
extra = 0
class ProduitAdmin(admin.ModelAdmin):
inlines = [ProduitTagsInline, ProduitDescriptionsInline]
exclude = ('descriptions', 'tags')
Olivier Pons / 2016
50 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Administration : ManyToMany
Olivier Pons / 2016
51 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Administration : même clé étrangère
→ models.py
class LangueTraduction(BaseModel):
src = models.ForeignKey('Langue', related_name='langue_src')
dst = models.ForeignKey('Langue', related_name='langue_dst')
nom = models.CharField(max_length=50)
→ admin.py
class LangueTraductionsInline(admin.TabularInline):
# ! fk_name = obligatoire sinon pas visible :
fk_name = 'src'
model = LangueTraduction
extra = 0
class LangueAdmin(admin.ModelAdmin):
inlines = [LangueTraductionsInline]
Olivier Pons / 2016
52 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Administration : même clé étrangère
Olivier Pons / 2016
53 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Traduction
Au moment où la fonction est appelée
from django.utils.translation import ugettext as _
Au moment où la chaîne est réellement utilisée
from django.utils.translation import ugettext_lazy as _
Créer un dosser ”locale” dans le projet
Avec manage.py shell :
makemessages -l fr
makemessages -l en
compilemessages
Olivier Pons / 2016
54 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Traduction
Pour qu'il charge ces chaines :
Dans settings.py, ajouter :
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
Olivier Pons / 2016
55 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Champs de type ImageField
Répertoire des fichiers ”téléversés” :
Dans settings.py, ajouter :
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
Puis dans urls.py, ajouter :
urlpatterns = [
...
url(r'^public/(?P<path>.*)$',
'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT}),
]
Olivier Pons / 2016
56 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Lancer des commandes SQL en direct
Exemple ici pour simuler le ”DESC [table]” de mysql :
Lancer python en ligne de commande
from django.db import connection
cursor = connection.cursor()
cursor.execute("PRAGMA table_info(ventegroupee)")
for row in cursor:
print(row)
Pour la note : cursor est une classe ”iterable”,
donc on peut faire un ”for” dessus
Olivier Pons / 2016
57 / 71
Technologies avancées
2 – Site basique
2 – Django – Suppléments
Outils Django déjà en production
Allez ici :
https://github.com/divio/django-cms
Installez le en suivant les instructions.
Olivier Pons / 2016
58 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Modèle exemple
Autre exemple models.py :
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
class CharacterClass(models.Model):
name = models.CharField(_(u'Nom de la Classe'),max_length=80)
playable = models.BooleanField(_(u'Le joueur peut le choisir'))
def __str__(self):
return self.name
Olivier Pons / 2016
59 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Modèle exemple
Types existants :
CharField
BooleanField
EmailField
PositiveIntegerField
TextField
ForeignKey
OneToOneField
ManyToManyField
Olivier Pons / 2016
60 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Modèle exemple
class CharacterManager(models.Manager):
def get_query_set(self):
return super(CharacterManager, self)\
.get_query_set()\
.filter(playable = True)
class CharacterClass(models.Model):
...
objects = models.Manager() # Manager par défaut
playable_character = CharacterManager() # Playable Manager
playable = CharacterClass.objects.filter(Playable = True)
playable = CharacterClass.playable_character.all()
Olivier Pons / 2016
61 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Vues génériques
monblog/urls.py
→ on peut y ajouter directement :
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^apropos/$', TemplateView.as_view(
template_name='apropos.html'
))
]
Olivier Pons / 2016
62 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Vues génériques : dérivation
# monapp/views.py
from django.views.generic import TemplateView
class AproposView(TemplateView):
template_name = "apropos.html"
# urls.py
from django.conf.urls import url
from monapp.views import AproposView
urlpatterns = [
url(r'^apropos/', AproposView.as_view()),
]
Olivier Pons / 2016
63 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Vues génériques : listes
class IndexView(generic.ListView):
template_name = 'produits/index.html'
context_object_name = 'liste_produits'
def get_queryset(self):
""" Dites ce que cela renvoie : """
return Produit.objects.order_by(
'-date_v_fin', '-date_v_debut'
)[:5]
Olivier Pons / 2016
64 / 71
Technologies avancées
2 – Site basique
3 – Django – Jeu de rôle
Vues génériques : détail
from django.views.generic.detail import DetailView
from django.utils import timezone
from .models import Produit
class MaDetailView(DetailView):
template_name = 'produits/detail.html'
model = Produit
def get_context_data(self, **kwargs):
context = super(MaDetailView, self)
.get_context_data(**kwargs)
context['now'] = timezone.now()
return context
Olivier Pons / 2016
65 / 71
Technologies avancées
2 – Site basique
3 – Django – Sujet à faire
Choisissez un site à faire parmi les suivants
Réservation de places de concert
Médiathèque
Blog multi-utilisateurs multi rôles
Vente de services (développement, formation)
Rencontre entre professionnels (”à la LinkedIn”)
SAAS de comptabilité basique
Création communautaire de livres
Présentation et statistiques détaillées d'un MMORPG
Crowdfunding (”à la kickstarter / indiegogo”)
Site d'apprentissage en ligne
Réservation de tables d'un restaurant
Olivier Pons / 2016
66 / 71
Technologies avancées
2 – Site basique
4 – Structure classique
Varnish
Configuration de varnish : /etc/varnish/default.vcl :
backend apache {
.host = "127.0.0.1";
.port = "8080";
}
backend nodejs {
.host = "127.0.0.1";
.port = "3000";
}
...
Olivier Pons / 2016
67 / 71
Technologies avancées
2 – Site basique
4 – Structure classique
Varnish
...
sub vcl_recv {
if (req.url ~ "(?i)\.(jpeg|jpg|...|html|htm)$") {
unset req.http.Cookie;
}
if (
(req.http.host ~ "olivierpons\.(.*)")
|| (req.http.host ~ "krystallopolis\.(.*)")
) {
set req.backend_hint = apache;
set req.http.X-Server = req.http.host;
}
...
Olivier Pons / 2016
68 / 71
Technologies avancées
2 – Site basique
4 – Structure classique
Varnish
...
# Surcharge pour NodeJS
if (
(req.http.host ~ "node\.wogwog\.(.*)")
) {
set req.backend_hint = nodejs;
set req.http.X-Server = req.http.host;
# "pass" = passer direct sans cache possible
return(pass);
}
}
...
Olivier Pons / 2016
69 / 71
Technologies avancées
2 – Site basique
4 – Structure classique
Varnish
...
sub vcl_deliver {
set resp.http.Server = "WTF Server";
# Supprimer toutes les signatures :
unset resp.http.Via;
unset resp.http.X-Powered-By;
unset resp.http.X-Varnish;
}
Olivier Pons / 2016
70 / 71
Technologies avancées
2 – Site basique
4 – Structure classique
Apache / NodeJS / Python
Apache
httpd.conf
Listen 8080
NodeJS
bin/www
var port = normalizePort(process.env.PORT || '3000');
Python / Django
python manage.py runserver 8080
Olivier Pons / 2016
71 / 71

Documents pareils