Projets Django

Presenter Notes

../_statics/emencia.png

Presenter Notes

Briques logiciels

Nos projets sont composés de plusieurs briques logicielles :

La plupart requiert l'emploi de la ligne de commande dans un terminal, celà est souvent contraignant sous Windows.

Processus d'intégration d'un projet

  1. Création d'un buildout du projet avec epaster;
  2. Installation du buildout;
  3. Configuration des applications;
  4. Intégration des templates et du CSS;

Presenter Notes

../_statics/figb.jpg

Presenter Notes

BUILDOUT

Presenter Notes

Quoi

Un outil de construction dirigée par de la configuration.

Pourquoi

  • Permet de cloisonner une installation
  • Rassemble tout les composants pour une installation rapide et automatisée
  • Pré-configure le projet Django

Comment

  • Créé avec epaster, notre outil de création de projets Django;
  • On y rassemble tout les outils et logiciels nécessaire au projet;
  • Installation dans un environnement virtuel qui cloisonne les briques logicielles;

Presenter Notes

../_statics/compass-logo.png

Presenter Notes

Quoi

Un outil en Ruby pour compiler des sources SCSS en CSS.

Pourquoi

Permet de développer en SCSS, plus souple et plus complet que CSS.

  • SCSS permet d'avoir des sources plus propres, plus lisibles, mieux structurées;
  • Compass ajoute à cela des fonctions utiles;

Comment

Génère des fichiers CSS à partir du code SCSS, soit à la demande, soit en continue avec détection des changements.

Presenter Notes

../_statics/django-logo-negative.png

Presenter Notes

Étapes

  • Structure
    • Settings
    • Urls
    • Views
    • Models
  • Assets
  • Templates
    • Les blocs
    • Les variables
    • Tags et filtres

Presenter Notes

Django : Structure

Presenter Notes

Settings

Contient tout les paramètres et options qui configurent Django et les applications installés.

Avec epaster, seul les settings pour configurer Django lui-même sont dans les fichiers de settings principaux (à la racine du projet) et les settings des applications sont rangés dans leur mods.

Nos projets contiennent plusieurs settings différents à utiliser selon l'environnement (intégration, production, etc..).

Presenter Notes

Views

Les vues (ou views) sont les éléments qui exposent les pages du site.

Une vue rassemble tout ce qui est nécessaire à la publication de son contenu :

  • Données de la base de données
  • Templates
  • Traitement de la requête
  • etc..

Puis compile le template à partir du contenu pour génèrer le HTML de la page qu'il représente.

Presenter Notes

Urls

Ce sont les chemins à utiliser pour accéder aux pages.

Les URLs sont matérialisés dans les applications par des fichiers urls.py, c'est une carte des chemins.

On y met la correspondance des URLs avec les vues qui doivent être utilisés pour générer la page ciblée par une URL.

Les applications définissent leurs URLs mais au final c'est la webapp qui contrôle quelles URLs seront utilisés.

Presenter Notes

Models

Les modèles de données sont les schémas permettant d'accéder aux données dans notre base de données.

Par exemple dans une liste de produits :

  • Pour chaque produit on utilise le modèle de données Produit qui définit le schéma des données disponible pour chaque produit;
  • Les produits partagent tous le même modèle de données Produit;
  • Chacun des produits possèdent ses propres données;
  • Chaque produit peut définir ou non certaines données de son modèle de données.

Presenter Notes

Django : Assets

Presenter Notes

Introduction

On considère comme assets, toute les sources textes qui servent à la mise en forme des pages, tel que les fichiers CSS et Javascripts. Les images ne sont pas considérés comme des assets car ce ne sont pas des fichiers textes mais des fichiers binaires.

Presenter Notes

django-assets

Au lieu de gérer les assets à l'unité et disperser leur chargement ici et là dans les templates, on utilise django-assets pour les gérer proprement.

On regroupe donc les assets d'un même type (Javascript, CSS) qui doivent fonctionner ensemble dans ce qu'on apelle un Bundle. Ainsi dans les templates où ils sont requis on charge les bundles nécessaires à la page qui regroupe tout les assets requis.

Bénéfices

  • Organisation cohérente des assets, plus de dispersions;
  • Groupement des assets dans un seul fichier de chaque type et minification du code pour accélérer le chargement des pages;

Attention à bien intégrer et utiliser les sources des assets et non pas leur version déjà minifiée (habituellement les fichiers du type *.min.js ou *.min.css).

Presenter Notes

Django : Templates

Presenter Notes

Introduction

Un template modélise comment doit être généré une page ou une de ses parties. Grossièrement, Django ouvre le template et remplace ses variables et ses blocs avec le contenu dont il dispose depuis sa view, puis renvoi le HTML produit.

Généralement les templates servent à produire du HTML, mais ils sont en fait capable de produire n'importe quel format de fichier texte.

Les vues fournissent toujours un context à leur template, ce contexte contient les variables disponibles (texte, chiffres, etc..), d'une vue à l'autre le contexte peut être différent.

Presenter Notes

Chargement

La convention est de les ranger dans un répertoire templates/ puis dans un répertoire du nom de l'application auxquels ils sont destinés.

Django possède un ordre de recherche particulier pour trouver un template, si un template foo.html est présent dans une app mais aussi dans la webapp, c'est celui de la webapp qui sera utilisé.

Parfois, on utilise un template par inclusion, c'est à dire qu'on l'apelle directement depuis le template sans que la vue en ait connaissance.

En général dans ce cas on nomme ce template d'inclusion d'une façon particulière par exemple _item.html (le caractère _ en premier) ou bien de le ranger dans un répertoire spécifique tel que includes/item.html.

Presenter Notes

Variables, filtres et tags

Le principe des templates de Django est de reconnaître trois types d'instructions :

  • Les variables : avec le motif {{ mavariable }};
  • Les tags : avec le motif {% montag %} ou bien le motif {% montag %}...{% endmontag %};
  • Les filtres qu'on peut adjoindre aux variables en utilisant le caractère |;

Pour finir il faut savoir que les motifs {{, }}, {%, %}, {# et #} sont réservés, vous ne pouvez pas les utiliser pour autre choses.

Presenter Notes

../_statics/holy_shit.jpg

Presenter Notes

Variables

Une variable provoque simplement le remplacement de son motif par la valeur de la variable du même nom dans le contexte du template.

Par défaut, Django échappe certains caractères du texte d'une variable :

  • < est converti en &lt;
  • > est converti en &gt;
  • ' est converti en &#39;
  • " est converti en &quot;
  • & est converti en &amp;

C'est une convention en HTML avec ces caractères spéciaux qui engendrent des problèmes car ils ont une signification particulière en HTML (< et > servent à créer un tag HTML). On peut utiliser le filtre |safe pour empêcher ce comportement.

Les variables inconnus (non présentes dans le contexte du template) ne provoquent aucun message d'erreur, Django supprime juste leur motif sans rien ajouter à la place.

Presenter Notes

Filtres

Ils permettent de filtrer la valeur d'une variable avant de l'injecter dans le HTML. Le filtre ne modifie pas la variable elle-même, uniquement son rendu dans le template.

On peut adjoindre un filtre à une variable en ajoutant un caractère | accolé après le nom de variable puis en ajoutant le filtre et ses arguments. Par exemple :

<p>{{ mavar|add:" world!" }}</p>

Si mavar vaut Hello, le résultat sera :

<p>Hello world!</p>

Certains filtres n'acceptent pas d'arguments.

Presenter Notes

Tags

Ce sont les éléments qui permettent de générer des fragments de HTML ou de contrôler certaines conditions à respecter pour appliquer un contenu.

C'est la pierre angulaire des templates car ils permettent de gérer et conditionner les variables et morceaux de HTML à employer.

En général les tags auto-fermés comme {% montag %} génèrent un fragment de HTML, et les tags à fermeture comme {% montag %}...{% endmontag %} conditionnent leur contenu. On ouvre un tag à fermeture avec sa balise ouvrante {% montag %}, on place son contenu puis on le ferme avec sa balise fermante {% endmontag %} qui est simplement le nom du tag précédé du mot end.

Django possède déjà de nombreux tags qui sont directement disponibles à tout moment dans le template, on dit qu'ils sont builtin (intégré).

Mais une application peut embarquer ses propres tags supplémentaires (custom), il faut alors les pré-chargés au moyen d'un tag builtin nommé {% load ... %}. La création d'un nouveau tag requiert du code Python.

Presenter Notes

L'intégration en pratique

Presenter Notes

L'héritage

Les templates peuvent hériter d'un autre template, soit pour y écraser certains blocs, soit pour les écraser complètement.

Le template dont hérite un autre template est appelé le template parent. Si foo.html hérite de skeleton.html, on dit que de``skeleton.html`` est le template parent de foo.html qui lui est son enfant.

Le template enfant n'a aucune connaissance directe des tags, inclusion et fragments HTML de son parent. Par contre il a accès au même contexte de template et il a connaissance des blocs du template parent.

L'héritage se fait avec le tag {% extends "TEMPLATE_NAME" %}TEMPLATE_NAME sera le chemin du template parent. Ce tag d'héritage lorsqu'il est utilisé doit toujours être le premier élément du template avant quoi que ce soit.

Il n'est pas rare qu'un template hérite de plusieurs autres templates pour achever la génération du contenu, il faut alors suivre le fil des blocs de contenus pour comprendre qui fait quoi et d'où provient tel ou tel HTML.

Presenter Notes

Les blocs

Un bloc est une partie d'un template que l'on nomme et qu'on délimite avec un tag de sorte qu'un template enfant peut écraser cette partie sans écraser tout le reste et devoir alors en recopier des parties. On délimite un bloc avec le motif {% block NOM_DU_BLOC %}ICI MON CONTENU{% endblock %}NOM_DU_BLOC est le nom du bloc, il ne doit contenir aucun caractères spéciaux ou caractères accentués, seulement des lettres et chiffres et le caractère _.

Par exemple on peut faire un template de base très simple, qu'on apellera skeleton.html :

<!DOCTYPE html>
<head>
    <title>Une page HTML</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>

Presenter Notes

Ce sera le squelette de base des templates des pages dont elles hériteront et dont elles pourront remplir la partie délimitée par le bloc nommé content. Par exemple le template foo.html suivant :

{% extends "skeleton.html" %}
{% block content %}
    <h1>Hello World!</h1>
{% endblock %}

Produira le HTML suivant :

<!DOCTYPE html>
<head>
    <title>Une page HTML</title>
</head>
<body>
    <h1>Hello World!</h1>
</body>
</html>

Un bloc peut aussi récupérer le contenu de son parent sans l'écraser, pour ajouter des informations mais en conservant le HTML généré par le template parent.

Presenter Notes

Par exemple le template bar.html suivant hérite de foo.html (et donc par cascade aussi de skeleton.html :

{% extends "foo.html" %}
{% block content %}
    {{ block.super }}
    <p>This is SPARTAAAAA!</p>
{% endblock %}

Produira le HTML suivant :

<!DOCTYPE html>
<head>
    <title>Une page HTML</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>This is SPARTAAAAA!</p>
</body>
</html>

Celà se fait avec le motif {{ block.super }} qu'on insère dans le bloc dont on veut récupérer le contenu de son parent, on peut placer ce motif n'importe où dans le bloc mais jamais en dehors.

Presenter Notes

Attention il y a plusieurs choses à savoir sur les blocs :

  • Le nom d'un bloc est unique à chaque template, c'est à dire qu'un même bloc ne peut se représenter plusieurs fois dans le même template, sinon Django renverra une erreur;
  • L'héritage d'un bloc est récursif, si un bloc hérite d'un bloc parent qui lui même hérite d'un autre bloc parent, le contenu des trois blocs est généré dans le HTML, l'héritage ne s'arrête pas juste au parent direct;
  • Un bloc n'est pas forcément à remplir, si il est définit dans un template parent mais que vous ne l'utilisez pas dans un template enfant, il n'y aura aucune erreur de Django;
  • Tout comme les variables, un bloc utilisé dans un template enfant mais qui n'existe pas dans un de ses templates parents ne provoquera aucun message d'erreur;

Presenter Notes

Le tag conditionnel IF

Le tag IF est un tag à fermeture, il permet de conditionner l'utilisation d'une partie selon que son expression soit vraie ou non :

{% if EXPRESSION %}
    Foo !
{% endif %}

Génère Foo ! uniquement si l'expression est vraie. On peut aussi avoir deux parties, la première étant utilisée si l'expression est vraie et la seconde si elle est fausse :

{% if EXPRESSION %}
    Foo !
{% else %}
    Bar !
{% endif %}

Génère Foo ! uniquement si l'expression est vraie, sinon si elle est fausse ce sera Bar !.

Presenter Notes

On peut aussi avoir plusieurs parties, chacune conditionnée avec leur propre expression :

{% if EXPRESSION_1 %}
    Foo !
{% elif EXPRESSION_2 %}
    Meuh !
{% elif EXPRESSION_3 %}
    Plop !
{% elif EXPRESSION_4 %}
    Coin !
{% else %}
    Bar !
{% endif %}

Les expressions sont parcourus dans l'ordre naturel (EXPRESSION_1, EXPRESSION_2, etc..), la première qui est vraie sera utilisée et si aucune n'est vraie, ce sera la dernière (après le {% else %}) qui sera finalement utilisée.

Presenter Notes

Le tag de boucle FOR

Le principe de boucler est de parcourir une liste d'éléments d'une variable et d'appliquer le contenu de la boucle pour chaque élément de la liste.

Dans l'instruction de la boucle, on indique que l'élément sera assigné sous un nom de variable temporaire à l'intérieur de la boucle pour pouvoir l'utiliser.

Il est possible d'imbriquer plusieurs boucles dans le cas ou des éléments d'une liste contiennent d'autres listes.

Par exemple avec une variable ma_liste qui contient une liste d'éléments "foo, meuh, plop, coin, bar", on instruit la boucle que l'élément courant doit être positionnée dans une variable nommée item :

{% for item in ma_liste %}
    <li>{{ item }}</li>
{% endfor %}

Et cela produira le HTML suivant :

<li>foo</li>
<li>meuh</li>
<li>plop</li>
<li>coin</li>
<li>bar</li>

Presenter Notes

Parfois on ouvre une boucle mais la variable dont elle dépend est une liste vide, du coup la boucle ne produira rien alors que l'on veut qu'elle produise quand même un élément neutre. C'est un peu comme la partie {% else %} d'un tag IF. Par exemple la boucle suivante :

{% for item in ma_liste %}
    <li>{{ item }}</li>
{% empty %}
    <li>Je suis tout vide</li>
{% endfor %}

Si ma_liste est effectivement une liste vide, cela produira le HTML suivant :

<li>Je suis tout vide</li>

Presenter Notes

Une boucle possède aussi une variable spéciale nommée forloop, cette variable contient des propriétés sur l'état de la boucle, les plus utilisés sont :

  • {{ forloop.counter }} qui renvoi la position de l'élément courant dans la liste, il commence toujours à 1;
  • {{ forloop.first }} qui est vrai si l'élément courant est le premier de la liste;
  • {{ forloop.last }} qui est vrai si l'élément courant est le dernier de la liste;

Presenter Notes

Le tag de commentaire

Ce tag est un tag particulier avec le même principe qu'un commentaire HTML si ce n'est que ses balises et son contenu n'apparaitront jamais dans le HTML généré.

  • Un commentaire se créé avec un tag {% comment %}...{% endcomment %}
  • Ou une version abrégée {# ... #}.

Un commentaire ne peut contenir d'autres instructions de commentaire sinon cela provoque une erreure.

Presenter Notes

Les tags de traductions

Django possède un système de traduction à partir de fichiers (*.po).

Il extrait des morceaux de textes qu'on lui indique dans les templates et en produit un fichier *.po qui est un dictionnaire à remplir pour chaque langue, le dictionnaire contiendra l'équivalent entre le texte à traduire et la traduction.

Lors de la génération HTML d'un template, Django y remplacera les textes marqués à traduire par la traduction selon la langue en cours.

Pour utiliser ces tags dans un template, on doit auparavant y charger son module nommé i18n au moyen du tag de chargement de modules {% load i18n %}.

  • Pour marquer un texte simple à traduire on utilise le tag simple {% trans 'MON TEXTE' %};
  • Pour marquer un texte long à traduire on utilise le tag {% blocktrans %}MON TEXTE{% endblocktrans %};

Les deux sont équivalents sauf que lorsqu'un texte contient des sauts de lignes ou du HTML, on doit toujours utiliser le second (blocktrans).

Presenter Notes

La fin est proche

Presenter Notes

../_statics/monster.png

Presenter Notes

Pour finir

La documentation est votre ami ! Elle est reconnue comme étant une documentation très pédagogique.

Actuellement chez Emencia, on tourne en Django 1.5. Et 2014 ne sera probablement pas notre année de passage en version 1.6.

La documentation originale en anglais est ici : https://docs.djangoproject.com/en/1.5/

Pour les réfractaires à l'anglais, une version française est disponible là : https://docs.djangoproject.com/fr/1.5/

Attention tout de même, car les habitués utilisent toujours des termes en anglais donc il peut y avoir quiproquo ou incompréhension si vous utilisez les termes de la documentation en français quand vous dialoguez avec eux.

Presenter Notes

../_statics/fonzie.png

Presenter Notes