From e60994e06525d27e0e71d300968b5e2a7e12cc6a Mon Sep 17 00:00:00 2001
From: Yohann D'ANELLO <yohann.danello@gmail.com>
Date: Wed, 23 Dec 2020 21:06:30 +0100
Subject: [PATCH] API Documentation

Signed-off-by: Yohann D'ANELLO <yohann.danello@gmail.com>
---
 apps/permission/api/views.py         |   2 +-
 docs/api/activity.rst                | 370 ++++++++++++++
 docs/api/basic.rst                   | 150 ++++++
 docs/{apps/api.rst => api/index.rst} |  13 +
 docs/api/logs.rst                    |  42 ++
 docs/api/member.rst                  | 476 ++++++++++++++++++
 docs/api/note.rst                    | 396 +++++++++++++++
 docs/api/permission.rst              |  82 ++++
 docs/api/treasury.rst                | 402 +++++++++++++++
 docs/api/wei.rst                     | 710 +++++++++++++++++++++++++++
 docs/apps/index.rst                  |  12 +-
 note_kfet/settings/base.py           |   1 +
 12 files changed, 2650 insertions(+), 6 deletions(-)
 create mode 100644 docs/api/activity.rst
 create mode 100644 docs/api/basic.rst
 rename docs/{apps/api.rst => api/index.rst} (98%)
 create mode 100644 docs/api/logs.rst
 create mode 100644 docs/api/member.rst
 create mode 100644 docs/api/note.rst
 create mode 100644 docs/api/permission.rst
 create mode 100644 docs/api/treasury.rst
 create mode 100644 docs/api/wei.rst

diff --git a/apps/permission/api/views.py b/apps/permission/api/views.py
index 10fd19e3..e6cb0d5d 100644
--- a/apps/permission/api/views.py
+++ b/apps/permission/api/views.py
@@ -32,4 +32,4 @@ class RoleViewSet(ReadOnlyProtectedModelViewSet):
     serializer_class = RoleSerializer
     filter_backends = [DjangoFilterBackend, SearchFilter]
     filterset_fields = ['name', 'permissions', 'for_club', 'memberships__user', ]
-    SearchFilter = ['$name', '$for_club__name', ]
+    search_fields = ['$name', '$for_club__name', ]
diff --git a/docs/api/activity.rst b/docs/api/activity.rst
new file mode 100644
index 00000000..99e730e5
--- /dev/null
+++ b/docs/api/activity.rst
@@ -0,0 +1,370 @@
+API Activités
+=============
+
+Activité
+--------
+
+**Chemin :** `/api/activity/activity/ <https://note.crans.org/api/activity/activity/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Activity List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Activity` objects, serialize it to JSON with the given serializer,\nthen render it on /api/activity/activity/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "description": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Description"
+              },
+              "location": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Lieu",
+                  "help_text": "Lieu o\u00f9 l'activit\u00e9 est organis\u00e9e, par exemple la Kfet.",
+                  "max_length": 255
+              },
+              "date_start": {
+                  "type": "datetime",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Date de d\u00e9but"
+              },
+              "date_end": {
+                  "type": "datetime",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Date de fin"
+              },
+              "valid": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Valide"
+              },
+              "open": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Ouvrir"
+              },
+              "activity_type": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Type"
+              },
+              "creater": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Utilisateur"
+              },
+              "organizer": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Organisateur",
+                  "help_text": "Le club qui organise l'activit\u00e9. Les co\u00fbts d'invitation iront pour ce club."
+              },
+              "attendees_club": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Club attendu",
+                  "help_text": "Club qui est autoris\u00e9 \u00e0 rejoindre l'activit\u00e9. Tr\u00e8s souvent le club Kfet."
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``description``
+* ``activity_type``
+* ``location``
+* ``creater``
+* ``organizer``
+* ``attendees_club``
+* ``date_start``
+* ``date_end``
+* ``valid``
+* ``open``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``description`` (expression régulière)
+* ``location`` (expression régulière)
+* ``creater__last_name`` (expression régulière)
+* ``creater__first_name`` (expression régulière)
+* ``creater__email`` (expression régulière)
+* ``creater__note__alias__name`` (expression régulière)
+* ``creater__note__alias__normalized_name`` (expression régulière)
+* ``organizer__name`` (expression régulière)
+* ``organizer__email`` (expression régulière)
+* ``organizer__note__alias__name`` (expression régulière)
+* ``organizer__note__alias__normalized_name`` (expression régulière)
+* ``attendees_club__name`` (expression régulière)
+* ``attendees_club__email`` (expression régulière)
+* ``attendees_club__note__alias__name`` (expression régulière)
+* ``attendees_club__note__alias__normalized_name`` (expression régulière)
+
+Type d'activité
+---------------
+
+**Chemin :** `/api/activity/type/ <https://note.crans.org/api/activity/type/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Activity Type List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `ActivityType` objects, serialize it to JSON with the given serializer,\nthen render it on /api/activity/type/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "manage_entries": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "G\u00e9rer les entr\u00e9es",
+                  "help_text": "Activer le support des entr\u00e9es pour cette activit\u00e9."
+              },
+              "can_invite": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Peut inviter"
+              },
+              "guest_entry_fee": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cotisation de l'entr\u00e9e invit\u00e9",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``manage_entries``
+* ``can_invite``
+* ``guest_entry_fee``
+
+Invité
+------
+
+**Chemin :** `/api/activity/guest/ <https://note.crans.org/api/activity/guest/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Guest List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Guest` objects, serialize it to JSON with the given serializer,\nthen render it on /api/activity/guest/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "last_name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom de famille",
+                  "max_length": 255
+              },
+              "first_name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Pr\u00e9nom",
+                  "max_length": 255
+              },
+              "activity": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Activity"
+              },
+              "inviter": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "H\u00f4te"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``activity``
+* ``activity__name``
+* ``last_name``
+* ``first_name``
+* ``inviter``
+* ``inviter__alias__name``
+* ``inviter__alias__normalized_name``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``activity__name`` (expression régulière)
+* ``last_name`` (expression régulière)
+* ``first_name`` (expression régulière)
+* ``inviter__user__email`` (expression régulière)
+* ``inviter__alias__name`` (expression régulière)
+* ``inviter__alias__normalized_name`` (expression régulière)
+
+Entrée
+------
+
+**Chemin :** `/api/activity/entry/ <https://note.crans.org/api/activity/entry/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Entry List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Entry` objects, serialize it to JSON with the given serializer,\nthen render it on /api/activity/entry/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "time": {
+                  "type": "datetime",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Heure d'entr\u00e9e"
+              },
+              "activity": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Activit\u00e9"
+              },
+              "note": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Note"
+              },
+              "guest": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Guest"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``activity``
+* ``time``
+* ``note``
+* ``guest``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``activity__name`` (expression régulière)
+* ``note__user__email`` (expression régulière)
+* ``note__alias__name`` (expression régulière)
+* ``note__alias__normalized_name`` (expression régulière)
+* ``guest__last_name`` (expression régulière)
+* ``guest__first_name`` (expression régulière)
+
diff --git a/docs/api/basic.rst b/docs/api/basic.rst
new file mode 100644
index 00000000..8ff28d9b
--- /dev/null
+++ b/docs/api/basic.rst
@@ -0,0 +1,150 @@
+API générale
+============
+
+Utilisateur
+-----------
+
+**Chemin :** `/api/user/ <https://note.crans.org/api/user/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "User List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `User` objects, serialize it to JSON with the given serializer,\nthen render it on /api/user/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "last_login": {
+                  "type": "datetime",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Derni\u00e8re connexion"
+              },
+              "is_superuser": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Statut super-utilisateur",
+                  "help_text": "Pr\u00e9cise que l'utilisateur poss\u00e8de toutes les permissions sans les assigner explicitement."
+              },
+              "username": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Pseudo",
+                  "help_text": "Requis. 150 caract\u00e8res maximum. Uniquement des lettres, nombres et les caract\u00e8res \u00ab\u00a0@\u00a0\u00bb, \u00ab\u00a0.\u00a0\u00bb, \u00ab\u00a0+\u00a0\u00bb, \u00ab\u00a0-\u00a0\u00bb et \u00ab\u00a0_\u00a0\u00bb.",
+                  "max_length": 150
+              },
+              "first_name": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Pr\u00e9nom",
+                  "max_length": 30
+              },
+              "last_name": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Nom de famille",
+                  "max_length": 150
+              },
+              "email": {
+                  "type": "email",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Adresse \u00e9lectronique",
+                  "max_length": 254
+              },
+              "is_staff": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Statut \u00e9quipe",
+                  "help_text": "Pr\u00e9cise si l'utilisateur peut se connecter \u00e0 ce site d'administration."
+              },
+              "is_active": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Actif",
+                  "help_text": "Pr\u00e9cise si l'utilisateur doit \u00eatre consid\u00e9r\u00e9 comme actif. D\u00e9cochez ceci plut\u00f4t que de supprimer le compte."
+              },
+              "date_joined": {
+                  "type": "datetime",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Date d'inscription"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``id``
+* ``username``
+* ``first_name``
+* ``last_name``
+* ``email``
+* ``is_superuser``
+* ``is_staff``
+* ``is_active``
+* ``note__alias__name``
+* ``note__alias__normalized_name``
+
+Type de contenu
+---------------
+
+**Chemin :** `/api/models/ <https://note.crans.org/api/models/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Content Type List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `User` objects, serialize it to JSON with the given serializer,\nthen render it on /api/models/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ]
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``id``
+* ``app_label``
+* ``model``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``app_label`` (expression régulière)
+* ``model`` (expression régulière)
+
diff --git a/docs/apps/api.rst b/docs/api/index.rst
similarity index 98%
rename from docs/apps/api.rst
rename to docs/api/index.rst
index 41087ec4..81834928 100644
--- a/docs/apps/api.rst
+++ b/docs/api/index.rst
@@ -1,6 +1,19 @@
 API
 ===
 
+.. toctree::
+   :maxdepth: 2
+   :caption: Applications
+
+   activity
+   basic
+   logs
+   member
+   note
+   permission
+   treasury
+   wei
+
 La NoteKfet2020 dispose d'une API REST. Elle est accessible sur `/api/ <https://note.crans.org/api/>`_.
 Elle supporte les requêtes GET, POST, HEAD, PUT, PATCH et DELETE (peut varier selon les pages).
 
diff --git a/docs/api/logs.rst b/docs/api/logs.rst
new file mode 100644
index 00000000..53f304c1
--- /dev/null
+++ b/docs/api/logs.rst
@@ -0,0 +1,42 @@
+API Logs
+========
+
+Journal de modification
+-----------------------
+
+**Chemin :** `/api/logs/ <https://note.crans.org/api/logs/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Changelog List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Changelog` objects, serialize it to JSON with the given serializer,\nthen render it on /api/logs/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ]
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``model``
+* ``action``
+* ``instance_pk``
+* ``user``
+* ``ip``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``timestamp``
+* ``id``
+
diff --git a/docs/api/member.rst b/docs/api/member.rst
new file mode 100644
index 00000000..88d4c874
--- /dev/null
+++ b/docs/api/member.rst
@@ -0,0 +1,476 @@
+API Membres
+===========
+
+Profil utilisateur
+------------------
+
+**Chemin :** `/api/members/profile/ <https://note.crans.org/api/members/profile/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Profile List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Profile` objects, serialize it to JSON with the given serializer,\nthen render it on /api/members/profile/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "phone_number": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Num\u00e9ro de t\u00e9l\u00e9phone",
+                  "max_length": 50
+              },
+              "section": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Section",
+                  "help_text": "e.g. \"1A0\", \"9A\u2665\", \"SAPHIRE\"",
+                  "max_length": 255
+              },
+              "department": {
+                  "type": "choice",
+                  "required": true,
+                  "read_only": false,
+                  "label": "D\u00e9partement",
+                  "choices": [
+                      {
+                          "value": "A0",
+                          "display_name": "Informatique (A0)"
+                      },
+                      {
+                          "value": "A1",
+                          "display_name": "Math\u00e9matiques (A1)"
+                      },
+                      {
+                          "value": "A2",
+                          "display_name": "Chimie (A''2)"
+                      },
+                      {
+                          "value": "A'2",
+                          "display_name": "Physique appliqu\u00e9e (A'2)"
+                      },
+                      {
+                          "value": "A3",
+                          "display_name": "Biologie (A3)"
+                      },
+                      {
+                          "value": "B1234",
+                          "display_name": "SAPHIRE (B1234)"
+                      },
+                      {
+                          "value": "B1",
+                          "display_name": "M\u00e9canique (B1)"
+                      },
+                      {
+                          "value": "B2",
+                          "display_name": "G\u00e9nie civil (B2)"
+                      },
+                      {
+                          "value": "B3",
+                          "display_name": "G\u00e9nie m\u00e9canique (B3)"
+                      },
+                      {
+                          "value": "B4",
+                          "display_name": "EEA (B4)"
+                      },
+                      {
+                          "value": "C",
+                          "display_name": "Design (C)"
+                      },
+                      {
+                          "value": "D2",
+                          "display_name": "\u00c9conomie-gestion (D2)"
+                      },
+                      {
+                          "value": "D3",
+                          "display_name": "Sciences sociales (D3)"
+                      },
+                      {
+                          "value": "E",
+                          "display_name": "Anglais (E)"
+                      },
+                      {
+                          "value": "EXT",
+                          "display_name": "Externe (EXT)"
+                      }
+                  ]
+              },
+              "promotion": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Promotion",
+                  "help_text": "Ann\u00e9e d'entr\u00e9e dans l'\u00e9cole (None si non-\u00e9tudiant\u00b7e de l'ENS)",
+                  "min_value": 0,
+                  "max_value": 32767
+              },
+              "address": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Adresse",
+                  "max_length": 255
+              },
+              "paid": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Pay\u00e9",
+                  "help_text": "Indique si l'utilisateur per\u00e7oit un salaire."
+              },
+              "ml_events_registration": {
+                  "type": "choice",
+                  "required": false,
+                  "read_only": false,
+                  "label": "S'inscrire sur la liste de diffusion pour rester inform\u00e9 des \u00e9v\u00e9nements sur le campus (1 mail par semaine)",
+                  "choices": [
+                      {
+                          "value": "",
+                          "display_name": "Non"
+                      },
+                      {
+                          "value": "fr",
+                          "display_name": "Oui (les recevoir en fran\u00e7ais)"
+                      },
+                      {
+                          "value": "en",
+                          "display_name": "Oui (les recevoir en anglais)"
+                      }
+                  ]
+              },
+              "ml_sport_registration": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "S'inscrire sur la liste de diffusion pour rester inform\u00e9 des actualit\u00e9s sportives sur le campus (1 mail par semaine)"
+              },
+              "ml_art_registration": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "S'inscrire sur la liste de diffusion pour rester inform\u00e9 des actualit\u00e9s artistiques sur le campus (1 mail par semaine)"
+              },
+              "report_frequency": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Fr\u00e9quence des rapports (en jours)",
+                  "min_value": 0,
+                  "max_value": 32767
+              },
+              "last_report": {
+                  "type": "datetime",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Date de dernier rapport"
+              },
+              "email_confirmed": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Adresse email confirm\u00e9e"
+              },
+              "registration_valid": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Inscription valide"
+              },
+              "user": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": true,
+                  "label": "User"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``user``
+* ``user__first_name``
+* ``user__last_name``
+* ``user__username``
+* ``user__email``
+* ``user__note__alias__name``
+* ``user__note__alias__normalized_name``
+* ``phone_number``
+* ``section``
+* ``department``
+* ``promotion``
+* ``address``
+* ``paid``
+* ``ml_events_registration``
+* ``ml_sport_registration``
+* ``ml_art_registration``
+* ``report_frequency``
+* ``email_confirmed``
+* ``registration_valid``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``user__first_name`` (expression régulière)
+* ``user__last_name`` (expression régulière)
+* ``user__username`` (expression régulière)
+* ``user__email`` (expression régulière)
+* ``user__note__alias__name`` (expression régulière)
+* ``user__note__alias__normalized_name`` (expression régulière)
+
+Club
+----
+
+**Chemin :** `/api/members/club/ <https://note.crans.org/api/members/club/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Club List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Club` objects, serialize it to JSON with the given serializer,\nthen render it on /api/members/club/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "email": {
+                  "type": "email",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Courriel",
+                  "max_length": 254
+              },
+              "require_memberships": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "N\u00e9cessite des adh\u00e9sions",
+                  "help_text": "D\u00e9cochez si ce club n'utilise pas d'adh\u00e9sions."
+              },
+              "membership_fee_paid": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cotisation pour adh\u00e9rer (normalien \u00e9l\u00e8ve)",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_fee_unpaid": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cotisation pour adh\u00e9rer (normalien \u00e9tudiant)",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_duration": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Dur\u00e9e de l'adh\u00e9sion",
+                  "help_text": "La dur\u00e9e maximale (en jours) d'une adh\u00e9sion (NULL = infinie).",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_start": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "D\u00e9but de l'adh\u00e9sion",
+                  "help_text": "Date \u00e0 partir de laquelle les adh\u00e9rents peuvent renouveler leur adh\u00e9sion."
+              },
+              "membership_end": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Fin de l'adh\u00e9sion",
+                  "help_text": "Date maximale d'une fin d'adh\u00e9sion, apr\u00e8s laquelle les adh\u00e9rents doivent la renouveler."
+              },
+              "parent_club": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Club parent"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``email``
+* ``note__alias__name``
+* ``note__alias__normalized_name``
+* ``parent_club``
+* ``parent_club__name``
+* ``require_memberships``
+* ``membership_fee_paid``
+* ``membership_fee_unpaid``
+* ``membership_duration``
+* ``membership_start``
+* ``membership_end``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``email`` (expression régulière)
+* ``note__alias__name`` (expression régulière)
+* ``note__alias__normalized_name`` (expression régulière)
+
+Adhésion
+--------
+
+**Chemin :** `/api/members/membership/ <https://note.crans.org/api/members/membership/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Membership List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Membership` objects, serialize it to JSON with the given serializer,\nthen render it on /api/members/membership/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "date_start": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "L'adh\u00e9sion commence le"
+              },
+              "date_end": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "L'adh\u00e9sion finit le"
+              },
+              "fee": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Cotisation",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "user": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Utilisateur"
+              },
+              "club": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Club"
+              },
+              "roles": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "R\u00f4les"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``club__name``
+* ``club__email``
+* ``club__note__alias__name``
+* ``club__note__alias__normalized_name``
+* ``user__username``
+* ``user__last_name``
+* ``user__first_name``
+* ``user__email``
+* ``user__note__alias__name``
+* ``user__note__alias__normalized_name``
+* ``date_start``
+* ``date_end``
+* ``fee``
+* ``roles``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``id``
+* ``date_start``
+* ``date_end``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``club__name`` (expression régulière)
+* ``club__email`` (expression régulière)
+* ``club__note__alias__name`` (expression régulière)
+* ``club__note__alias__normalized_name`` (expression régulière)
+* ``user__username`` (expression régulière)
+* ``user__last_name`` (expression régulière)
+* ``user__first_name`` (expression régulière)
+* ``user__email`` (expression régulière)
+* ``user__note__alias__name`` (expression régulière)
+* ``user__note__alias__normalized_name`` (expression régulière)
+* ``roles__name`` (expression régulière)
+
diff --git a/docs/api/note.rst b/docs/api/note.rst
new file mode 100644
index 00000000..21d4c987
--- /dev/null
+++ b/docs/api/note.rst
@@ -0,0 +1,396 @@
+API Note
+========
+
+Note
+----
+
+**Chemin :** `/api/note/note/ <https://note.crans.org/api/note/note/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Note Polymorphic List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Note` objects (with polymorhism),\nserialize it to JSON with the given serializer,\nthen render it on /api/note/note/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {}
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``alias__name``
+* ``polymorphic_ctype``
+* ``is_active``
+* ``balance``
+* ``last_negative``
+* ``created_at``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``alias__name``
+* ``alias__normalized_name``
+* ``balance``
+* ``created_at``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``alias__normalized_name`` (expression régulière)
+* ``alias__name`` (expression régulière)
+* ``polymorphic_ctype__model`` (expression régulière)
+* ``noteuser__user__last_name`` (expression régulière)
+* ``noteuser__user__first_name`` (expression régulière)
+* ``noteuser__user__email`` (expression régulière)
+* ``noteuser__user__email`` (expression régulière)
+* ``noteclub__club__email`` (expression régulière)
+
+Alias
+-----
+
+**Chemin :** `/api/note/alias/ <https://note.crans.org/api/note/alias/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Alias List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Alias` objects, serialize it to JSON with the given serializer,\nthen render it on /api/aliases/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "normalized_name": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": true,
+                  "label": "Normalized name"
+              },
+              "note": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Note"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``note``
+* ``note__noteuser__user``
+* ``note__noteclub__club``
+* ``note__polymorphic_ctype__model``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``name``
+* ``normalized_name``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``normalized_name`` (expression régulière)
+* ``name`` (expression régulière)
+* ``note__polymorphic_ctype__model`` (expression régulière)
+
+Alias
+-----
+
+**Chemin :** `/api/note/consumer/ <https://note.crans.org/api/note/consumer/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Consumer List",
+      "description": "",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ]
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``note``
+* ``note__noteuser__user``
+* ``note__noteclub__club``
+* ``note__polymorphic_ctype__model``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``name``
+* ``normalized_name``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``normalized_name`` (expression régulière)
+* ``name`` (expression régulière)
+* ``note__polymorphic_ctype__model`` (expression régulière)
+
+Catégorie de transaction
+------------------------
+
+**Chemin :** `/api/note/transaction/category/ <https://note.crans.org/api/note/transaction/category/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Template Category List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `TemplateCategory` objects, serialize it to JSON with the given serializer,\nthen render it on /api/note/transaction/category/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 31
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``templates``
+* ``templates__name``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``templates__name`` (expression régulière)
+
+Modèle de transaction
+---------------------
+
+**Chemin :** `/api/note/transaction/template/ <https://note.crans.org/api/note/transaction/template/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Transaction Template List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `TransactionTemplate` objects, serialize it to JSON with the given serializer,\nthen render it on /api/note/transaction/template/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "amount": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Montant",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "display": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Afficher"
+              },
+              "highlighted": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Mis en avant"
+              },
+              "description": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Description",
+                  "max_length": 255
+              },
+              "destination": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Destination"
+              },
+              "category": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Type"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``amount``
+* ``display``
+* ``category``
+* ``category__name``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``amount``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``category__name`` (expression régulière)
+
+Transaction
+-----------
+
+**Chemin :** `/api/note/transaction/transaction/ <https://note.crans.org/api/note/transaction/transaction/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Transaction List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Transaction` objects, serialize it to JSON with the given serializer,\nthen render it on /api/note/transaction/transaction/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {}
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``source``
+* ``source_alias``
+* ``source__alias__name``
+* ``source__alias__normalized_name``
+* ``destination``
+* ``destination_alias``
+* ``destination__alias__name``
+* ``destination__alias__normalized_name``
+* ``quantity``
+* ``polymorphic_ctype``
+* ``amount``
+* ``created_at``
+* ``valid``
+* ``invalidity_reason``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``created_at``
+* ``amount``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``reason`` (expression régulière)
+* ``source_alias`` (expression régulière)
+* ``source__alias__name`` (expression régulière)
+* ``source__alias__normalized_name`` (expression régulière)
+* ``destination_alias`` (expression régulière)
+* ``destination__alias__name`` (expression régulière)
+* ``destination__alias__normalized_name`` (expression régulière)
+* ``invalidity_reason`` (expression régulière)
+
diff --git a/docs/api/permission.rst b/docs/api/permission.rst
new file mode 100644
index 00000000..b94a5c13
--- /dev/null
+++ b/docs/api/permission.rst
@@ -0,0 +1,82 @@
+API Permissions
+===============
+
+Permission
+----------
+
+**Chemin :** `/api/permission/permission/ <https://note.crans.org/api/permission/permission/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Permission List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Permission` objects, serialize it to JSON with the given serializer,\nthen render it on /api/permission/permission/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ]
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``model``
+* ``type``
+* ``query``
+* ``mask``
+* ``field``
+* ``permanent``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``model__name`` (expression régulière)
+* ``query`` (expression régulière)
+* ``description`` (expression régulière)
+
+Permissions par rôles
+---------------------
+
+**Chemin :** `/api/permission/roles/ <https://note.crans.org/api/permission/roles/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Role List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `RolePermission` objects, serialize it to JSON with the given serializer\nthen render it on /api/permission/roles/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ]
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``permissions``
+* ``for_club``
+* ``memberships__user``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``for_club__name`` (expression régulière)
+
diff --git a/docs/api/treasury.rst b/docs/api/treasury.rst
new file mode 100644
index 00000000..ed470221
--- /dev/null
+++ b/docs/api/treasury.rst
@@ -0,0 +1,402 @@
+API Trésorerie
+==============
+
+Facture
+-------
+
+**Chemin :** `/api/treasury/invoice/ <https://note.crans.org/api/treasury/invoice/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Invoice List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Invoice` objects, serialize it to JSON with the given serializer,\nthen render it on /api/treasury/invoice/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Num\u00e9ro de facture",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "products": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": true,
+                  "label": "Products"
+              },
+              "bde": {
+                  "type": "choice",
+                  "required": false,
+                  "read_only": true,
+                  "label": "BDE"
+              },
+              "object": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Objet",
+                  "max_length": 255
+              },
+              "description": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Description"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "address": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Adresse"
+              },
+              "date": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Date"
+              },
+              "acquitted": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Acquitt\u00e9e"
+              },
+              "locked": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Verrouill\u00e9e",
+                  "help_text": "Une facture ne peut plus \u00eatre modifi\u00e9e si elle est verrouill\u00e9e."
+              },
+              "tex": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Fichier TeX source"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``bde``
+* ``object``
+* ``description``
+* ``name``
+* ``address``
+* ``date``
+* ``acquitted``
+* ``locked``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``object`` (expression régulière)
+* ``description`` (expression régulière)
+* ``name`` (expression régulière)
+* ``address`` (expression régulière)
+
+Produit
+-------
+
+**Chemin :** `/api/treasury/product/ <https://note.crans.org/api/treasury/product/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Product List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Product` objects, serialize it to JSON with the given serializer,\nthen render it on /api/treasury/product/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "designation": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "D\u00e9signation",
+                  "max_length": 255
+              },
+              "quantity": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Quantit\u00e9",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "amount": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Prix unitaire",
+                  "min_value": -2147483648,
+                  "max_value": 2147483647
+              },
+              "invoice": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Facture"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``invoice``
+* ``designation``
+* ``quantity``
+* ``amount``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``designation`` (expression régulière)
+* ``invoice__object`` (expression régulière)
+
+Type de remise
+--------------
+
+**Chemin :** `/api/treasury/remittance_type/ <https://note.crans.org/api/treasury/remittance_type/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Remittance Type List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `RemittanceType` objects, serialize it to JSON with the given serializer\nthen render it on /api/treasury/remittance_type/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "note": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Note"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``note``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``note__special_type`` (expression régulière)
+
+Remise
+------
+
+**Chemin :** `/api/treasury/remittance/ <https://note.crans.org/api/treasury/remittance/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Remittance List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Remittance` objects, serialize it to JSON with the given serializer,\nthen render it on /api/treasury/remittance/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "transactions": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": true,
+                  "label": "Transactions"
+              },
+              "date": {
+                  "type": "datetime",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Date"
+              },
+              "comment": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Commentaire",
+                  "max_length": 255
+              },
+              "closed": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Ferm\u00e9e"
+              },
+              "remittance_type": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Type"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``date``
+* ``remittance_type``
+* ``comment``
+* ``closed``
+* ``transaction_proxies__transaction``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``remittance_type__note__special_type`` (expression régulière)
+* ``comment`` (expression régulière)
+
+Crédit de la société générale
+-----------------------------
+
+**Chemin :** `/api/treasury/soge_credit/ <https://note.crans.org/api/treasury/soge_credit/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Soge Credit List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `SogeCredit` objects, serialize it to JSON with the given serializer,\nthen render it on /api/treasury/soge_credit/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "user": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Utilisateur"
+              },
+              "credit_transaction": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Transaction de cr\u00e9dit"
+              },
+              "transactions": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Transactions d'adh\u00e9sion"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``user``
+* ``user__last_name``
+* ``user__first_name``
+* ``user__email``
+* ``user__note__alias__name``
+* ``user__note__alias__normalized_name``
+* ``transactions``
+* ``credit_transaction``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``user__last_name`` (expression régulière)
+* ``user__first_name`` (expression régulière)
+* ``user__email`` (expression régulière)
+* ``user__note__alias__name`` (expression régulière)
+* ``user__note__alias__normalized_name`` (expression régulière)
+
diff --git a/docs/api/wei.rst b/docs/api/wei.rst
new file mode 100644
index 00000000..8c92c026
--- /dev/null
+++ b/docs/api/wei.rst
@@ -0,0 +1,710 @@
+API WEI
+=======
+
+Wei
+---
+
+**Chemin :** `/api/wei/club/ <https://note.crans.org/api/wei/club/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Wei Club List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `WEIClub` objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/club/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "email": {
+                  "type": "email",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Courriel",
+                  "max_length": 254
+              },
+              "require_memberships": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "N\u00e9cessite des adh\u00e9sions",
+                  "help_text": "D\u00e9cochez si ce club n'utilise pas d'adh\u00e9sions."
+              },
+              "membership_fee_paid": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cotisation pour adh\u00e9rer (normalien \u00e9l\u00e8ve)",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_fee_unpaid": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cotisation pour adh\u00e9rer (normalien \u00e9tudiant)",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_duration": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Dur\u00e9e de l'adh\u00e9sion",
+                  "help_text": "La dur\u00e9e maximale (en jours) d'une adh\u00e9sion (NULL = infinie).",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "membership_start": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "D\u00e9but de l'adh\u00e9sion",
+                  "help_text": "Date \u00e0 partir de laquelle les adh\u00e9rents peuvent renouveler leur adh\u00e9sion."
+              },
+              "membership_end": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Fin de l'adh\u00e9sion",
+                  "help_text": "Date maximale d'une fin d'adh\u00e9sion, apr\u00e8s laquelle les adh\u00e9rents doivent la renouveler."
+              },
+              "year": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Ann\u00e9e",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "date_start": {
+                  "type": "date",
+                  "required": true,
+                  "read_only": false,
+                  "label": "D\u00e9but"
+              },
+              "date_end": {
+                  "type": "date",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Fin"
+              },
+              "parent_club": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Club parent"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``year``
+* ``date_start``
+* ``date_end``
+* ``email``
+* ``note__alias__name``
+* ``note__alias__normalized_name``
+* ``parent_club``
+* ``parent_club__name``
+* ``require_memberships``
+* ``membership_fee_paid``
+* ``membership_fee_unpaid``
+* ``membership_duration``
+* ``membership_start``
+* ``membership_end``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``email`` (expression régulière)
+* ``note__alias__name`` (expression régulière)
+* ``note__alias__normalized_name`` (expression régulière)
+
+Bus
+---
+
+**Chemin :** `/api/wei/bus/ <https://note.crans.org/api/wei/bus/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Bus List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `Bus` objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/bus/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "description": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Description"
+              },
+              "information_json": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Informations sur le questionnaire",
+                  "help_text": "Informations sur le sondage pour les nouveaux membres, encod\u00e9es en JSON"
+              },
+              "wei": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "WEI"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``wei``
+* ``description``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``wei__name`` (expression régulière)
+* ``description`` (expression régulière)
+
+Équipe de bus
+-------------
+
+**Chemin :** `/api/wei/team/ <https://note.crans.org/api/wei/team/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Bus Team List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `BusTeam` objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/team/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "color": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Couleur",
+                  "help_text": "La couleur du T-Shirt, stock\u00e9 sous la forme de son \u00e9quivalent num\u00e9rique",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "description": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Description"
+              },
+              "bus": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Bus"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``bus``
+* ``color``
+* ``description``
+* ``bus__wei``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+* ``bus__name`` (expression régulière)
+* ``bus__wei__name`` (expression régulière)
+* ``description`` (expression régulière)
+
+Rôle au wei
+-----------
+
+**Chemin :** `/api/wei/role/ <https://note.crans.org/api/wei/role/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Wei Role List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `WEIRole` objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/role/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom",
+                  "max_length": 255
+              },
+              "for_club": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "S'applique au club"
+              },
+              "permissions": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Permissions"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``name``
+* ``permissions``
+* ``memberships``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``name`` (expression régulière)
+
+Participant au wei
+------------------
+
+**Chemin :** `/api/wei/registration/ <https://note.crans.org/api/wei/registration/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Wei Registration List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all WEIRegistration objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/registration/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "soge_credit": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Cr\u00e9dit de la Soci\u00e9t\u00e9 g\u00e9n\u00e9rale"
+              },
+              "caution_check": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Ch\u00e8que de caution donn\u00e9"
+              },
+              "birth_date": {
+                  "type": "date",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Date de naissance"
+              },
+              "gender": {
+                  "type": "choice",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Genre",
+                  "choices": [
+                      {
+                          "value": "male",
+                          "display_name": "Homme"
+                      },
+                      {
+                          "value": "female",
+                          "display_name": "Femme"
+                      },
+                      {
+                          "value": "nonbinary",
+                          "display_name": "Non-binaire"
+                      }
+                  ]
+              },
+              "clothing_cut": {
+                  "type": "choice",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Coupe de v\u00eatement",
+                  "choices": [
+                      {
+                          "value": "male",
+                          "display_name": "Homme"
+                      },
+                      {
+                          "value": "female",
+                          "display_name": "Femme"
+                      }
+                  ]
+              },
+              "clothing_size": {
+                  "type": "choice",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Taille de v\u00eatement",
+                  "choices": [
+                      {
+                          "value": "XS",
+                          "display_name": "XS"
+                      },
+                      {
+                          "value": "S",
+                          "display_name": "S"
+                      },
+                      {
+                          "value": "M",
+                          "display_name": "M"
+                      },
+                      {
+                          "value": "L",
+                          "display_name": "L"
+                      },
+                      {
+                          "value": "XL",
+                          "display_name": "XL"
+                      },
+                      {
+                          "value": "XXL",
+                          "display_name": "XXL"
+                      }
+                  ]
+              },
+              "health_issues": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Probl\u00e8mes de sant\u00e9"
+              },
+              "emergency_contact_name": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Nom du contact en cas d'urgence",
+                  "max_length": 255
+              },
+              "emergency_contact_phone": {
+                  "type": "string",
+                  "required": true,
+                  "read_only": false,
+                  "label": "T\u00e9l\u00e9phone du contact en cas d'urgence",
+                  "max_length": 32
+              },
+              "first_year": {
+                  "type": "boolean",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Premi\u00e8re ann\u00e9e",
+                  "help_text": "Indique si l'utilisateur est nouveau dans l'\u00e9cole."
+              },
+              "information_json": {
+                  "type": "string",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Informations sur l'inscription",
+                  "help_text": "Informations sur l'inscription (bus pour les 2A+, questionnaire pour les 1A), encod\u00e9es en JSON"
+              },
+              "user": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Utilisateur"
+              },
+              "wei": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "WEI"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``user``
+* ``user__username``
+* ``user__first_name``
+* ``user__last_name``
+* ``user__email``
+* ``user__note__alias__name``
+* ``user__note__alias__normalized_name``
+* ``wei``
+* ``wei__name``
+* ``wei__email``
+* ``wei__year``
+* ``soge_credit``
+* ``caution_check``
+* ``birth_date``
+* ``gender``
+* ``clothing_cut``
+* ``clothing_size``
+* ``first_year``
+* ``emergency_contact_name``
+* ``emergency_contact_phone``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``user__username`` (expression régulière)
+* ``user__first_name`` (expression régulière)
+* ``user__last_name`` (expression régulière)
+* ``user__email`` (expression régulière)
+* ``user__note__alias__name`` (expression régulière)
+* ``user__note__alias__normalized_name`` (expression régulière)
+* ``wei__name`` (expression régulière)
+* ``wei__email`` (expression régulière)
+* ``health_issues`` (expression régulière)
+* ``emergency_contact_name`` (expression régulière)
+* ``emergency_contact_phone`` (expression régulière)
+
+Adhésion au wei
+---------------
+
+**Chemin :** `/api/wei/membership/ <https://note.crans.org/api/wei/membership/>`_
+
+Options
+~~~~~~~
+
+.. code:: json
+
+  {
+      "name": "Wei Membership List",
+      "description": "REST API View set.\nThe djangorestframework plugin will get all `BusTeam` objects, serialize it to JSON with the given serializer,\nthen render it on /api/wei/membership/",
+      "renders": [
+          "application/json",
+          "text/html"
+      ],
+      "parses": [
+          "application/json",
+          "application/x-www-form-urlencoded",
+          "multipart/form-data"
+      ],
+      "actions": {
+          "POST": {
+              "id": {
+                  "type": "integer",
+                  "required": false,
+                  "read_only": true,
+                  "label": "ID"
+              },
+              "date_start": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "L'adh\u00e9sion commence le"
+              },
+              "date_end": {
+                  "type": "date",
+                  "required": false,
+                  "read_only": false,
+                  "label": "L'adh\u00e9sion finit le"
+              },
+              "fee": {
+                  "type": "integer",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Cotisation",
+                  "min_value": 0,
+                  "max_value": 2147483647
+              },
+              "user": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Utilisateur"
+              },
+              "club": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "Club"
+              },
+              "bus": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Bus"
+              },
+              "team": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "\u00c9quipe"
+              },
+              "registration": {
+                  "type": "field",
+                  "required": false,
+                  "read_only": false,
+                  "label": "Inscription au WEI"
+              },
+              "roles": {
+                  "type": "field",
+                  "required": true,
+                  "read_only": false,
+                  "label": "R\u00f4les"
+              }
+          }
+      }
+  }
+
+Filtres Django
+~~~~~~~~~~~~~~
+
+* ``club__name``
+* ``club__email``
+* ``club__note__alias__name``
+* ``club__note__alias__normalized_name``
+* ``user__username``
+* ``user__last_name``
+* ``user__first_name``
+* ``user__email``
+* ``user__note__alias__name``
+* ``user__note__alias__normalized_name``
+* ``date_start``
+* ``date_end``
+* ``fee``
+* ``roles``
+* ``bus``
+* ``bus__name``
+* ``team``
+* ``team__name``
+* ``registration``
+
+Tris possible
+~~~~~~~~~~~~~
+
+* ``id``
+* ``date_start``
+* ``date_end``
+
+Filtres de recherche
+~~~~~~~~~~~~~~~~~~~~
+
+* ``club__name`` (expression régulière)
+* ``club__email`` (expression régulière)
+* ``club__note__alias__name`` (expression régulière)
+* ``club__note__alias__normalized_name`` (expression régulière)
+* ``user__username`` (expression régulière)
+* ``user__last_name`` (expression régulière)
+* ``user__first_name`` (expression régulière)
+* ``user__email`` (expression régulière)
+* ``user__note__alias__name`` (expression régulière)
+* ``user__note__alias__normalized_name`` (expression régulière)
+* ``roles__name`` (expression régulière)
+* ``bus__name`` (expression régulière)
+* ``team__name`` (expression régulière)
+
diff --git a/docs/apps/index.rst b/docs/apps/index.rst
index 6810be56..d8f07ae1 100644
--- a/docs/apps/index.rst
+++ b/docs/apps/index.rst
@@ -9,15 +9,17 @@ Applications de la NoteKfet2020
    note/index
    activity
    permission
-   api
+   ../api/index
    registration
    logs
    treasury
    wei
 
 La NoteKfet est un projet Django, décomposé en applications.
-Certaines Applications sont développées uniquement pour ce projet, et sont indispensables, d'autre sont packagé et sont installées comme dépendances.
-Enfin Des fonctionnalités annexes ont été rajouté, mais ne sont pas essentiel au déploiement de la NoteKfet; leur usage est cependant recommandé.
+Certaines Applications sont développées uniquement pour ce projet, et sont indispensables,
+d'autres sont packagesé et sont installées comme dépendances.
+Enfin des fonctionnalités annexes ont été rajouté, mais ne sont pas essentiel au déploiement de la NoteKfet;
+leur usage est cependant recommandé.
 
 Le front utilise le framework Bootstrap4 et quelques morceaux de javascript custom.
 
@@ -34,7 +36,7 @@ Applications indispensables
    La gestion des Activités (créations, gestion, entrée...)
 * `Permission <permission>`_ :
    Backend de droits, limites les pouvoirs des utilisateurs
-* `API <api>`_ :
+* `API <../api>`_ :
    API REST de la note, est notamment utilisée pour rendre la note dynamique
    (notamment la page de conso)
 * `Registration <registration>`_ :
@@ -54,7 +56,7 @@ Applications packagées
 * ``django_tables2``
     utiliser pour afficher des tables de données et les formater, en python plutôt qu'en HTML.
 * ``restframework``
-    Base de l'`API <api>`_.
+    Base de l'`API <../api>`_.
 
 Applications facultatives
 -------------------------
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index 1cbf6ed7..7009be6f 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -49,6 +49,7 @@ INSTALLED_APPS = [
     'django.contrib.staticfiles',
     'django.forms',
     'django_filters',
+    'django_extensions',
 
     # API
     'rest_framework',
-- 
GitLab