This commit is contained in:
Declerfayt Cedric 2015-12-28 14:29:49 +01:00
commit fb84f07a6d
8 changed files with 98 additions and 38 deletions

View File

@ -1 +1,2 @@
sphinx sphinx
sphinx_rtd_theme

View File

@ -2,4 +2,4 @@
Administration Administration
============== ==============
.. include admin/advices.rst .. include:: admin/advices.rst

View File

@ -11,16 +11,16 @@ Lors de la définition d'une nouvelle classe, et puisque l'ORM se base sur Activ
Une représentation textuelle Une représentation textuelle
============================ ============================
Surcharger la fonction `def __str__(self)` sur la classe permettra de retourner une chaîne de caractère qui représentera l'instance de la classe. Cette information est utilisée un peu partout dans le code, et donnera une meilleure idée de ce qu'on manipule. Surcharger la fonction ``def __str__(self)`` sur la classe permettra de retourner une chaîne de caractère qui représentera l'instance de la classe. Cette information est utilisée un peu partout dans le code, et donnera une meilleure idée de ce qu'on manipule.
En plus, c'est aussi ceci qui est appelé lorsque l'admin de Django historisera une action (et ceci sera inaltérable). En plus, c'est aussi ceci qui est appelé lorsque l'admin de Django historisera une action (et ceci sera inaltérable).
URL absolue URL absolue
=========== ===========
La méthode `def get_absolute_url(self)` retourne l'URL à laquelle on peut envoyer une requête pour obtenir le maximum d'informations La méthode `def get_absolute_url(self)` retourne l'URL à laquelle on peut envoyer une requête pour obtenir le maximum d'informations
concernant cette instance. concernant cette instance.
Par exemple: Par exemple:
.. code-block:: python .. code-block:: python
@ -44,7 +44,7 @@ Meta
Titre Titre
===== =====
Le titre de l'administration peut être modifié de deux manières: Le titre de l'administration peut être modifié de deux manières:
* Soit en modifiant le template de l'administration * Soit en modifiant le template de l'administration
* Soit en ajoutant l'assignation suivante dans le fichier `urls.py`: `admin.site.site_header = "SuperBook Secret Area`. * Soit en ajoutant l'assignation suivante dans le fichier `urls.py`: `admin.site.site_header = "SuperBook Secret Area`.
@ -52,5 +52,4 @@ Le titre de l'administration peut être modifié de deux manières:
Greffons Greffons
======== ========
L'interface d'administration est extensible dans une certaine mesure. Notamment utiliser ``django_extensions`` pour avoir les ForeignKey auto-complétées. L'interface d'administration est extensible dans une certaine mesure. Notamment utiliser ``django_extensions`` pour avoir les ForeignKey auto-complétées.

View File

@ -17,6 +17,8 @@ import sys
import os import os
import shlex import shlex
import sphinx_rtd_theme
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here. # documentation root, use os.path.abspath to make it absolute, like shown here.
@ -111,7 +113,7 @@ todo_include_todos = True
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
html_theme = 'alabaster' html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
@ -119,7 +121,7 @@ html_theme = 'alabaster'
#html_theme_options = {} #html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = [] html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# The name for this set of Sphinx documents. If None, it defaults to # The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation". # "<project> v<release> documentation".

View File

@ -17,7 +17,6 @@ Contents:
specs specs
models models
views views
templates
forms forms
admin admin
integration integration
@ -29,4 +28,3 @@ Indices and tables
* :ref:`genindex` * :ref:`genindex`
* :ref:`modindex` * :ref:`modindex`
* :ref:`search` * :ref:`search`

View File

@ -13,7 +13,7 @@ Les morceaux de code seront développés pour Python3.4+ et Django 1.8+. Ils né
Création de l'environnement Création de l'environnement
=========================== ===========================
Commencez par créer un environnement virtuel, afin d'y stocker les dépendances. Vérifiez dans votre fichier `~/.bashrc` (ou tout fichier lancé au démarrage de votre session) que la variable ``WORKON_HOME`` est bien définie. Faites ensuite un `source` sur le fichier `virtualenvwrapper.sh` (à adapter en fonction de votre distribution): Commencez par créer un environnement virtuel, afin d'y stocker les dépendances. Vérifiez dans votre fichier ``~/.bashrc`` (ou tout fichier lancé au démarrage de votre session) que la variable ``WORKON_HOME`` est bien définie. Faites ensuite un ``source`` sur le fichier ``virtualenvwrapper.sh`` (à adapter en fonction de votre distribution):
.. code-block:: shell .. code-block:: shell
@ -26,7 +26,7 @@ Commencez par créer un environnement virtuel, afin d'y stocker les dépendances
L'intérêt de ceci ? Ne pas devoir se soucier de l'emplacement des environnements virtuels, et pouvoir entièrement les découpler des sources sur lesquelles vous travaillez, en plus d'isoler le code, de créer un containeur pour les dépendances et d'être indépendant des librairies tierces déjà installées sur le système. L'intérêt de ceci ? Ne pas devoir se soucier de l'emplacement des environnements virtuels, et pouvoir entièrement les découpler des sources sur lesquelles vous travaillez, en plus d'isoler le code, de créer un containeur pour les dépendances et d'être indépendant des librairies tierces déjà installées sur le système.
Lancez `mkvirtualenv gwift-env`. Lancez ``mkvirtualenv gwift-env``.
.. code-block:: shell .. code-block:: shell
@ -42,9 +42,9 @@ Ceci créera l'arborescence de fichiers suivante, qui peut à nouveau être un p
$ ls gwift-env $ ls gwift-env
Include/ Lib/ Scripts/ Include/ Lib/ Scripts/
Nous pouvons ensuite l'activer grâce à la commande `source gwift-env/bin/activate` avec `virtualenv` et `workon gwift-env` avec `virtualenvwrapper`. Nous pouvons ensuite l'activer grâce à la commande ``source gwift-env/bin/activate`` avec ``virtualenv`` et ``workon gwift-env`` avec ``virtualenvwrapper``.
A présent, tous les binaires présents dans cet environnement prendront le pas sur les binaires du système. De la même manière, une variable *PATH* propre est définie et utilisée, afin que les librairies Python soient stockées dans le répertoire `gwift-env/Lib/site-packages/`. C'est notamment ici que nous retrouverons le code-source de Django, ainsi que des librairies externes une fois que nous les aurons installées. A présent, tous les binaires présents dans cet environnement prendront le pas sur les binaires du système. De la même manière, une variable ``PATH`` propre est définie et utilisée, afin que les librairies Python soient stockées dans le répertoire ``gwift-env/Lib/site-packages/``. C'est notamment ici que nous retrouverons le code-source de Django, ainsi que des librairies externes une fois que nous les aurons installées.
.. code-block:: shell .. code-block:: shell
@ -60,7 +60,7 @@ A présent, tous les binaires présents dans cet environnement prendront le pas
Fichiers sources Fichiers sources
================ ================
Nous commençons par créer le répertoire du projet, à savoir `gwift-project`. Nous commençons par créer le répertoire du projet, à savoir ``gwift-project``.
.. code-block:: shell .. code-block:: shell
@ -69,7 +69,7 @@ Nous commençons par créer le répertoire du projet, à savoir `gwift-project`.
Comme l'environnement est activé, on peut à présent y installer Django. La librairie restera indépendante du reste du système, et ne polluera pas les autres projets. Comme l'environnement est activé, on peut à présent y installer Django. La librairie restera indépendante du reste du système, et ne polluera pas les autres projets.
C'est parti: `pip install django`! C'est parti: ``pip install django``!
.. code-block:: shell .. code-block:: shell
@ -80,15 +80,15 @@ C'est parti: `pip install django`!
Installing collected packages: django Installing collected packages: django
Successfully installed django-1.8.4 Successfully installed django-1.8.4
Les commandes de création d'un nouveau site sont à présent disponibles, la principale étant `django-admin startproject`. Par la suite, nous utiliserons `manage.py`, qui constitue un *wrapper* autour de `django-admin`. Les commandes de création d'un nouveau site sont à présent disponibles, la principale étant ``django-admin startproject``. Par la suite, nous utiliserons ``manage.py``, qui constitue un *wrapper* autour de `django-admin`.
Pour démarrer notre projet, nous lançons `django-admin startproject gwift`. Pour démarrer notre projet, nous lançons ``django-admin startproject gwift``.
.. code-block:: shell .. code-block:: shell
$ django-admin startproject gwift $ django-admin startproject gwift
Cette action aura pour effet de créer un nouveau dossier `gwift`, dans lequel on trouve la structure suivante: Cette action aura pour effet de créer un nouveau dossier ``gwift``, dans lequel on trouve la structure suivante:
.. code-block:: shell .. code-block:: shell
@ -111,14 +111,14 @@ Chacun de ces fichiers sert à:
Gestion des dépendances Gestion des dépendances
======================= =======================
Comme nous venons d'ajouter une dépendance à notre projet, nous allons créer un fichier reprenant tous les dépendances de notre projet. Ceux-ci sont placés normalement dans un fichier `requirements.txt`. Dans un premier temps, ce fichier peut être placé directement à la racine du projet, mais on préférera rapidement le déplacer dans un sous-répertoire spécifique (`requirements`), afin de grouper les dépendances en fonction de leur utilité: Comme nous venons d'ajouter une dépendance à notre projet, nous allons créer un fichier reprenant tous les dépendances de notre projet. Ceux-ci sont placés normalement dans un fichier ``requirements.txt``. Dans un premier temps, ce fichier peut être placé directement à la racine du projet, mais on préférera rapidement le déplacer dans un sous-répertoire spécifique (``requirements``), afin de grouper les dépendances en fonction de leur utilité:
* `base.txt` * ``base.txt``
* `dev.txt` * ``dev.txt``
* `staging.txt` * ``staging.txt``
* `production.txt` * ``production.txt``
Au début de chaque fichier, il suffira d'ajouter la ligne `-r base.txt`, puis de lancer l'installation grâce à un `pip install -r <nom du fichier>`. De cette manière, il est tout à fait acceptable de n'installer `flake8` et `django-debug-toolbar` qu'en développement par exemple. Dans l'immédiat, ajoutez simplement `django` dans le fichier `requirements/base.txt`. Au début de chaque fichier, il suffira d'ajouter la ligne ``-r base.txt``, puis de lancer l'installation grâce à un ``pip install -r <nom du fichier>``. De cette manière, il est tout à fait acceptable de n'installer `flake8` et `django-debug-toolbar` qu'en développement par exemple. Dans l'immédiat, ajoutez simplement ``django`` dans le fichier ``requirements/base.txt``.
.. code-block:: shell .. code-block:: shell

View File

@ -14,13 +14,13 @@ On voit bien ici le principe de **contexte**: l'application viendra avec son mod
Gestion Gestion
======= =======
Comme expliqué un peu plus haut, le fichier `manage.py` est un *wrapper* sur les commandes `django-admin`. A partir de maintenant, nous n'utiliserons plus que celui-là pour tout ce qui touchera à la gestion de notre projet: Comme expliqué un peu plus haut, le fichier ``manage.py`` est un *wrapper* sur les commandes ``django-admin``. A partir de maintenant, nous n'utiliserons plus que celui-là pour tout ce qui touchera à la gestion de notre projet:
* `manage.py check` pour vérifier que votre projet ne rencontre aucune erreur * ``manage.py check`` pour vérifier que votre projet ne rencontre aucune erreur
* `manage.py runserver` pour lancer un serveur de développement * ``manage.py runserver`` pour lancer un serveur de développement
* `manage.py test` pour découvrir les tests unitaires disponibles et les lancer. * ``manage.py test`` pour découvrir les tests unitaires disponibles et les lancer.
La liste complète peut être affichée avec `manage.py help`. Vous remarquerez que ces commandes sont groupées: La liste complète peut être affichée avec ``manage.py help``. Vous remarquerez que ces commandes sont groupées:
* **auth**: création d'un nouveau super-utilisateur, changer le mot de passe pour un utilisateur existant. * **auth**: création d'un nouveau super-utilisateur, changer le mot de passe pour un utilisateur existant.
* **django**: vérifier la *compliance* du projet, lancer un *shell*, *dumper* les données de la base, effectuer une migration du schéma, ... * **django**: vérifier la *compliance* du projet, lancer un *shell*, *dumper* les données de la base, effectuer une migration du schéma, ...

View File

@ -11,7 +11,7 @@ Le langage Python fonctionne avec un système d'améliorations basées sur des p
La PEP qui nous intéresse plus particulièrement pour la suite est la `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_, ou "Style Guide for Python Code". Elle spécifie des conventions d'organisation et de formatage de code Python, quelles sont les conventions pour l'indentation, le nommage des variables et des classes, etc. En bref, elle décrit comment écrire du code proprement pour que d'autres développeurs puissent le reprendre facilement, ou simplement que votre base de code ne dérive lentement vers un seuil de non-maintenabilité. La PEP qui nous intéresse plus particulièrement pour la suite est la `PEP-8 <https://www.python.org/dev/peps/pep-0008/>`_, ou "Style Guide for Python Code". Elle spécifie des conventions d'organisation et de formatage de code Python, quelles sont les conventions pour l'indentation, le nommage des variables et des classes, etc. En bref, elle décrit comment écrire du code proprement pour que d'autres développeurs puissent le reprendre facilement, ou simplement que votre base de code ne dérive lentement vers un seuil de non-maintenabilité.
Sur cette base, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: pep8. Pour l'installer, passez par pip. Lancez ensuite la commande pep8 suivie du chemin à analyser (., le nom d'un répertoire, le nom d'un fichier `.py`, ...). Si vous souhaitez uniquement avoir le nombre d'erreur de chaque type, saisissez les options `--statistics -qq`. Sur cette base, un outil existe et listera l'ensemble des conventions qui ne sont pas correctement suivies dans votre projet: pep8. Pour l'installer, passez par pip. Lancez ensuite la commande pep8 suivie du chemin à analyser (``.``, le nom d'un répertoire, le nom d'un fichier ``.py``, ...). Si vous souhaitez uniquement avoir le nombre d'erreur de chaque type, saisissez les options ``--statistics -qq``.
.. code-block:: shell .. code-block:: shell
@ -26,25 +26,85 @@ Sur cette base, un outil existe et listera l'ensemble des conventions qui ne son
13 E202 whitespace before '}' 13 E202 whitespace before '}'
86 E203 whitespace before ':' 86 E203 whitespace before ':'
Si vous ne voulez pas être dérangé sur votre manière de coder, et que vous voulez juste avoir un retour sur une analyse de votre code, essayez `pyflakes`: il analysera vos sources à la recherche de sources d'erreurs possibles (imports inutilisés, méthodes inconnues, etc.). Si vous ne voulez pas être dérangé sur votre manière de coder, et que vous voulez juste avoir un retour sur une analyse de votre code, essayez ``pyflakes``: il analysera vos sources à la recherche de sources d'erreurs possibles (imports inutilisés, méthodes inconnues, etc.).
Finalement, la solution qui couvre ces deux domaines existe et s'intitule `flake8 <https://github.com/PyCQA/flake8>`_. Sur base la même interface que `pep8`, vous aurez en plus tous les avantages liés à `pyflakes` concernant votre code source. Finalement, la solution qui couvre ces deux domaines existe et s'intitule `flake8 <https://github.com/PyCQA/flake8>`_. Sur base la même interface que ``pep8``, vous aurez en plus tous les avantages liés à ``pyflakes`` concernant votre code source.
Tests et couverture de code Tests et couverture de code
=========================== ===========================
La couverture de code donne un pourcentage lié à la quantité de code couvert par les testss. La couverture de code donne un pourcentage lié à la quantité de code couvert par les testss.
Attention que celle-ci ne permet pas de vérifier que le code est **bien** testé, elle permet juste de vérifier que le code est **testé**. Pour chaque fonction ou *statement* présent. Attention que celle-ci ne permet pas de vérifier que le code est **bien** testé, elle permet juste de vérifier que le code est **testé**. En Python, il existe le paquet `coverage <https://pypi.python.org/pypi/coverage/>`_, qui se charge d'évaluer le pourcentage de code couvert par les tests. Si cela vous intéresse, ajoutez-le dans le fichier ``requirements/base.txt``, et lancez une couverture de code grâce à la commande ``coverage``. La configuration peut se faire dans un fichier ``.coveragerc`` que vous placerez à la racine de votre projet, et qui sera lu lors de l'exécution.
// TODO .. code-block:: shell
# requirements/base.text
[...]
coverage
.. code-block:: shell
# .coveragerc to control coverage.py
[run]
branch = True
omit = ../*migrations*
[report]
ignore_errors = True
[html]
directory = coverage_html_report
.. code-block:: shell
$ coverage run --source "." manage.py test
$ coverage report
Name Stmts Miss Cover
---------------------------------------------
gwift\gwift\__init__.py 0 0 100%
gwift\gwift\settings.py 17 0 100%
gwift\gwift\urls.py 5 5 0%
gwift\gwift\wsgi.py 4 4 0%
gwift\manage.py 6 0 100%
gwift\wish\__init__.py 0 0 100%
gwift\wish\admin.py 1 0 100%
gwift\wish\models.py 49 16 67%
gwift\wish\tests.py 1 1 0%
gwift\wish\views.py 6 6 0%
---------------------------------------------
TOTAL 89 32 64%
$ coverage html
Ceci vous affichera non seulement la couverture de code estimée, et générera également vos fichiers sources avec les branches non couvertes. Pour gagner un peu de temps, n'hésitez pas à créer un fichier ``Makefile`` à la racine du projet. L'exemple ci-dessous permettra, grâce à la commande ``make coverage``, d'arriver au même résultat que ci-dessus:
.. code-block:: shell
# Makefile for gwift
#
# User-friendly check for coverage
ifeq ($(shell which coverage >/dev/null 2>&1; echo $$?), 1)
$(error The 'coverage' command was not found. Make sure you have coverage installed)
endif
.PHONY: help coverage
help:
@echo " coverage to run coverage check of the source files."
coverage:
coverage run --source='.' manage.py test; coverage report; coverage html;
@echo "Testing of coverage in the sources finished."
Complexité de McCabe Complexité de McCabe
==================== ====================
La `complexité cyclomatique <https://fr.wikipedia.org/wiki/Nombre_cyclomatique>`_ (ou complexité de McCabe) peut s'apparenter à une [...] La `complexité cyclomatique <https://fr.wikipedia.org/wiki/Nombre_cyclomatique>`_ (ou complexité de McCabe) peut s'apparenter à une [...]
A nouveau, un greffon pour `flake8` existe et donnera une estimation de la complexité de McCabe pour les fonctions trop complexes. Installez-le avec `pip install mccabe`, et activez-le avec le paramètre `--max-complexity`. Toute fonction dans la complexité est supérieure à 10 est considérée comme trop complexe. A nouveau, un greffon pour ``flake8`` existe et donnera une estimation de la complexité de McCabe pour les fonctions trop complexes. Installez-le avec `pip install mccabe`, et activez-le avec le paramètre `--max-complexity`. Toute fonction dans la complexité est supérieure à 10 est considérée comme trop complexe.
// TODO // TODO