Project Development

Version 163 (Jeremy Barneron, 10/27/2016 05:57 pm)

1 1 Etienne Pallier
h1. Project Development
2 2 Etienne Pallier
3 1 Etienne Pallier
4 143 Etienne Pallier
This page describes the development process, and some useful tools.
5 2 Etienne Pallier
6 2 Etienne Pallier
7 145 Etienne Pallier
{{>toc}}
8 145 Etienne Pallier
9 145 Etienne Pallier
10 145 Etienne Pallier
---
11 145 Etienne Pallier
12 145 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}USEFUL LINKS%
13 145 Etienne Pallier
14 145 Etienne Pallier
15 163 Jeremy Barneron
* Django.test Client : https://docs.djangoproject.com/fr/1.10/topics/testing/tools/
16 163 Jeremy Barneron
17 158 Etienne Pallier
* Pyros Demo online (intranet) : http://hyperion2.irap.omp.eu:8000/routine_manager/
18 158 Etienne Pallier
19 143 Etienne Pallier
* I-notify: http://linuxfr.org/news/exploiter-inotify-c-est-simple
20 84 Paul Carensac
21 143 Etienne Pallier
* Project Installation page : [[Project Installation]]
22 1 Etienne Pallier
23 143 Etienne Pallier
* HOWTO Format Redmine Wiki : http://www.redmine.org/projects/redmine/wiki/FrRedmineWikiFormatting
24 1 Etienne Pallier
25 143 Etienne Pallier
* Project's applications : [[Pyros applications]]
26 103 Etienne Pallier
27 143 Etienne Pallier
* Technical components : [[Technical components]]
28 1 Etienne Pallier
29 102 Etienne Pallier
* History of commits : https://gitlab.irap.omp.eu/epallier/pyros/commits/master
30 143 Etienne Pallier
31 130 Etienne Pallier
* OLD pyros version doc (Alexandru) : https://projects.irap.omp.eu/projects/gft/wiki/Documentation_technique_projet
32 130 Etienne Pallier
33 143 Etienne Pallier
34 143 Etienne Pallier
35 143 Etienne Pallier
36 2 Etienne Pallier
37 2 Etienne Pallier
38 2 Etienne Pallier
---
39 3 Etienne Pallier
40 112 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}TODO LIST%
41 112 Etienne Pallier
42 118 Etienne Pallier
 * Ajouter la possibilité de planifier les séquences de la liste "to be planned" de CADOR: http://cador.obs-hp.fr/ros/scenes_cador.php
43 112 Etienne Pallier
44 118 Etienne Pallier
 * Ajouter des boutons de navigation sur le planning, permettant de passer au planning précédent (historique), ou suivant, ou de revenir à celui du jour : <PREC> <NOW> <SUCC>
45 114 Etienne Pallier
46 118 Etienne Pallier
 * Ecrire algo général de soumission des sequences aux devices (telescope et cameras), en montrant les différents niveaux de boucles : seq, album, plan (et synchro à la fin d'une seq)
47 114 Etienne Pallier
48 118 Etienne Pallier
 * Compléter la grammaire de commandes PYROS à destination des telescopes et cameras (en essayant de faire des mises en commun)
49 117 Etienne Pallier
50 125 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}PLAN OF WORK (ROADMAP)%
51 122 Etienne Pallier
52 1 Etienne Pallier
53 133 Etienne Pallier
Le stage se déroule du 14 mars au 12 aout, soit environ 5 mois, soit exactement 22 semaines (S1 à S22), ou 44 demi-semaines.
54 132 Etienne Pallier
_*(Ne pas oublier de rédiger le rapport de stage au fur et à mesure)*_
55 132 Etienne Pallier
56 132 Etienne Pallier
Voir le détail de la roadmap: https://projects.irap.omp.eu/projects/inventirap/roadmap
57 132 Etienne Pallier
58 128 Etienne Pallier
All steps below are to be understood with included refactoring, testing, and documenting (in code and on wiki),
59 128 Etienne Pallier
and updating of the Dashboard module
60 1 Etienne Pallier
61 126 Etienne Pallier
* Full Workflow based on Celery (starting from alert reception and until analysis) : 1 week
62 1 Etienne Pallier
63 128 Etienne Pallier
* AlertManager + RequestBuilder : 2-3 weeks
64 128 Etienne Pallier
65 126 Etienne Pallier
* Scheduler (to be integrated in this new architecture, and completed) : 1 week
66 124 Etienne Pallier
67 1 Etienne Pallier
* RoutineManager (+ RequestBuilder) : 2-3 weeks
68 124 Etienne Pallier
69 129 Etienne Pallier
* ObservationManager : 2-3 weeks
70 1 Etienne Pallier
71 124 Etienne Pallier
* AnalysisManager: 2 weeks
72 129 Etienne Pallier
73 1 Etienne Pallier
* Environment Monitoring : observation conditions, weather, site (PLC), and instruments status : 2 weeks
74 132 Etienne Pallier
75 132 Etienne Pallier
76 132 Etienne Pallier
77 132 Etienne Pallier
78 132 Etienne Pallier
|                    |  |_.Prévu |_.Réalisé |
79 135 Etienne Pallier
|/2=.S01 (14/3-18/3) |.1|/2=<."Version 0.1 - wiki + git + easy install (from script)":https://projects.irap.omp.eu/versions/53|/2=<.version 1.1|
80 132 Etienne Pallier
                     |.2|
81 135 Etienne Pallier
|/2=.S02 (21/3-25/3) |.1|/42=<."Version 0.2 - wiki + git + easy install (from script)":https://projects.irap.omp.eu/versions/53|_/42=<.version 0.2 (en cours...)|
82 132 Etienne Pallier
                     |.2|
83 135 Etienne Pallier
|/2=.S03 (28/3-01/4) |.1|
84 132 Etienne Pallier
                     |.2|
85 135 Etienne Pallier
|/2=.S04 (04/4-08/4) |.1|
86 132 Etienne Pallier
                     |.2|
87 135 Etienne Pallier
|/2=.S05 (11/4-15/4) |.1|
88 132 Etienne Pallier
                     |.2|
89 132 Etienne Pallier
|/2=.S06 (18/4-22/4) |.1|
90 135 Etienne Pallier
                     |.2|
91 132 Etienne Pallier
|/2=.S07 (25/4-29/4) |.1|
92 132 Etienne Pallier
                     |.2|
93 132 Etienne Pallier
|/2=.S08 (02/5-06/5) |.1|
94 135 Etienne Pallier
                     |.2|
95 139 Etienne Pallier
|/2=.S09 (09/5-13/5) |.1|
96 135 Etienne Pallier
                     |.2|
97 140 Etienne Pallier
|/2=.S10 (16/5-20/5) |.1|
98 132 Etienne Pallier
                     |.2|
99 141 Etienne Pallier
|/2=.S11 (23/5-27/5) |.1|
100 132 Etienne Pallier
                     |.2|
101 151 Etienne Pallier
|/2=.S12 (30/5-03/6) |.1|
102 135 Etienne Pallier
                     |.2|
103 134 Etienne Pallier
|/2=.S13 (06/6-10/6) |.1|
104 1 Etienne Pallier
                     |.2|
105 151 Etienne Pallier
|_/2=.S14 (13/6-17/6) |.1|
106 1 Etienne Pallier
                     |.2|
107 134 Etienne Pallier
|/2=.S15 (20/6-24/6) |.1|
108 134 Etienne Pallier
                     |.2|
109 134 Etienne Pallier
|/2=.S16 (27/6-01/7) |.1|
110 134 Etienne Pallier
                     |.2|
111 134 Etienne Pallier
|/2=.S17 (04/7-08/7) |.1|
112 134 Etienne Pallier
                     |.2|
113 134 Etienne Pallier
|/2=.S18 (11/7-15/7) |.1|
114 134 Etienne Pallier
                     |.2|
115 134 Etienne Pallier
|/2=.S19 (18/7-22/7) |.1|
116 134 Etienne Pallier
                     |.2|
117 134 Etienne Pallier
|/2=.S20 (25/7-29/7) |.1|
118 134 Etienne Pallier
                     |.2|
119 134 Etienne Pallier
|/2=.S21 (01/8-05/8) |.1|
120 134 Etienne Pallier
                     |.2|
121 134 Etienne Pallier
|/2=.S22 (08/8-12/8) |.1|
122 134 Etienne Pallier
                     |.2|
123 132 Etienne Pallier
124 132 Etienne Pallier
125 136 Etienne Pallier
126 132 Etienne Pallier
---
127 136 Etienne Pallier
128 136 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}COMMIT PROCEDURE%
129 136 Etienne Pallier
130 136 Etienne Pallier
131 136 Etienne Pallier
Voici les différentes étapes à respecter au moment de chaque commit:
132 136 Etienne Pallier
133 136 Etienne Pallier
*1) S'assurer que tous les tests passent toujours...*
134 136 Etienne Pallier
135 153 Etienne Pallier
*2) Mettre à jour la version du ou des module(s) modifié(s)*
136 153 Etienne Pallier
(dans pyros/settings.py)
137 1 Etienne Pallier
138 152 Etienne Pallier
*3) Mettre à jour le fichier README (ceci est un exemple, un template)*
139 152 Etienne Pallier
140 136 Etienne Pallier
Date: 11/05/2016
141 137 Etienne Pallier
Version: 0.2.9
142 136 Etienne Pallier
Mise à jour doc install
143 136 Etienne Pallier
(Attention, changement structure BDD)
144 136 Etienne Pallier
Demande (terminée): https://projects.irap.omp.eu/issues/3542
145 137 Etienne Pallier
Version majeure en cours (0.2): https://projects.irap.omp.eu/versions/101
146 136 Etienne Pallier
147 136 Etienne Pallier
Remarques:
148 137 Etienne Pallier
=> Version: 0.2.9 = 9ème commit sur la version 0.2
149 136 Etienne Pallier
=> préciser "(bugfix)" si c'est le cas
150 136 Etienne Pallier
=> ajouter "(Attention, changement structure BDD)" s'il y a eu une modif de la BDD
151 136 Etienne Pallier
=> "Demande (terminée)" ou "Demande (en cours)", ou pas de demande du tout (exceptionnellement)
152 136 Etienne Pallier
=> ces infos permettront de savoir quelle version (et date) exacte du projet on a actuellement sur son disque
153 1 Etienne Pallier
154 136 Etienne Pallier
155 152 Etienne Pallier
*[4) Si c'est la fin d'une version majeure (0.1, 0.2, 0.3, ...)]*
156 136 Etienne Pallier
157 136 Etienne Pallier
* On doit normalement avoir écrit quelques nouveaux tests pour cette version !!!
158 136 Etienne Pallier
* Ajouter cette version en tête de la section "MAIN CHANGES (MILESTONES)" dans le fichier README
159 136 Etienne Pallier
* Mettre à jour la doc install/INSTALLATION à partir du wiki (si nécessaire)
160 1 Etienne Pallier
* Tester une installation du logiciel from scratch 
161 136 Etienne Pallier
162 136 Etienne Pallier
163 152 Etienne Pallier
*5) pull*
164 1 Etienne Pallier
165 136 Etienne Pallier
(au cas où quelqu'un d'autre aurait fait un push)
166 136 Etienne Pallier
167 136 Etienne Pallier
168 152 Etienne Pallier
*6) commit*
169 136 Etienne Pallier
170 136 Etienne Pallier
Reprendre dans le message de commit, faire un simple copier/coller des infos du fichier README (sauf date):
171 136 Etienne Pallier
172 136 Etienne Pallier
Version: 0.2.9
173 1 Etienne Pallier
Mise à jour doc install (bugfix)
174 136 Etienne Pallier
Demande (terminée): https://projects.irap.omp.eu/issues/3542
175 138 Etienne Pallier
Version majeure en cours (0.2): https://projects.irap.omp.eu/versions/101
176 136 Etienne Pallier
177 136 Etienne Pallier
178 152 Etienne Pallier
*[7) push]*
179 136 Etienne Pallier
180 136 Etienne Pallier
(seulement si le commit est important/urgent, ou suite à un ensemble de commits sur un même thème)
181 136 Etienne Pallier
182 122 Etienne Pallier
183 100 Etienne Pallier
---
184 3 Etienne Pallier
185 1 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}DOCUMENTS%
186 1 Etienne Pallier
187 1 Etienne Pallier
188 101 Etienne Pallier
189 146 Etienne Pallier
* Module Planner (Scheduler) : https://projects.irap.omp.eu/attachments/download/2607/IRAP-OFT-CC-SP-0007.pdf
190 146 Etienne Pallier
191 146 Etienne Pallier
192 148 Etienne Pallier
* DOC Paul: https://drive.google.com/folderview?id=0BzmdbXGIqXXMQ3JMTWRyakJyVVU&usp=sharing_eid&ts=571a3c9d
193 148 Etienne Pallier
194 146 Etienne Pallier
* Grammaire (workflow pseudo code): https://docs.google.com/document/d/1wG8Ha8xzEiRdA1I76sN9Te4Gq2ehq48SzFjSTaYRhfA/edit
195 57 Etienne Pallier
196 56 Etienne Pallier
197 24 Etienne Pallier
---
198 3 Etienne Pallier
199 144 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}OTHER USEFUL LINKS%
200 105 Etienne Pallier
201 105 Etienne Pallier
 * CADOR (A Klotz):
202 105 Etienne Pallier
203 106 Etienne Pallier
  * CADOR (portail de tous les telescopes) : http://cador.obs-hp.fr/ros/manual/cador_actions.html
204 106 Etienne Pallier
(click on "Manage", "CGI", or "Majordome")
205 106 Etienne Pallier
(or click on "Sequenced scenes" 1-5, each one is relative to a telescope underneath)
206 107 Etienne Pallier
(or click on "Rejected scenes" 1-5)
207 108 Etienne Pallier
  * Requests list: http://cador.obs-hp.fr/ros/manage/manage/liste_requete.php?hashuser=mdhxdjfu2scsrnfy2ry9
208 110 Etienne Pallier
  * Accès manuel: http://cador.obs-hp.fr/ros/manual
209 111 Etienne Pallier
  * Liste des scenes (sequences) TO BE PLANNED: http://cador.obs-hp.fr/ros/scenes_cador.php
210 70 Etienne Pallier
  * Historique des plannings : http://cador.obs-hp.fr/ros/sequenced/
211 119 Etienne Pallier
212 149 Etienne Pallier
 * VOEvent:
213 150 Etienne Pallier
214 149 Etienne Pallier
  * Protocole VTP: http://wiki.ivoa.net/twiki/bin/view/IVOA/VTPRFC
215 149 Etienne Pallier
216 119 Etienne Pallier
 * Celery: http://celery.readthedocs.org/en/latest/getting-started/first-steps-with-celery.html#first-steps
217 120 Etienne Pallier
218 121 Etienne Pallier
 * Created new user 'pyros' with password 'DjangoPyros'
219 70 Etienne Pallier
220 4 Etienne Pallier
 * pyrossu : pyrossu!
221 86 Etienne Pallier
222 86 Etienne Pallier
 * Alexandru work: https://projects.irap.omp.eu/projects/gft/wiki/Documentation_technique_projet#Fetch-the-project-from-github-via-git
223 71 Etienne Pallier
224 71 Etienne Pallier
 * readonly admin interface : https://gist.github.com/aaugustin/1388243
225 4 Etienne Pallier
226 4 Etienne Pallier
 * Liens vers web local :
227 4 Etienne Pallier
228 4 Etienne Pallier
  * homepage: http://localhost:8000
229 25 Etienne Pallier
  * admin: http://localhost:8000/admin
230 25 Etienne Pallier
231 26 Etienne Pallier
 * Eclipse:
232 26 Etienne Pallier
 
233 25 Etienne Pallier
  * Shift-Ctrl-f (ou Shift-Cmd-f) : reformatage du fichier selon PEP8
234 4 Etienne Pallier
  * Shift-Ctrl-1 : make doc string ...
235 4 Etienne Pallier
236 4 Etienne Pallier
 * Django:
237 80 Etienne Pallier
238 79 Etienne Pallier
  * Un répertoire de modules : https://www.djangopackages.com/
239 1 Etienne Pallier
  * Extensions
240 1 Etienne Pallier
241 83 Etienne Pallier
   * *django_jenkins* : intégration à Jenkins
242 83 Etienne Pallier
   * *factory_boy* : création de grappes de données pour les tests
243 83 Etienne Pallier
   
244 83 Etienne Pallier
    * https://factoryboy.readthedocs.org/en/latest/introduction.html
245 79 Etienne Pallier
    * https://factoryboy.readthedocs.org/en/latest/orms.html 
246 79 Etienne Pallier
247 79 Etienne Pallier
  * Modules très utilisés:
248 79 Etienne Pallier
249 79 Etienne Pallier
   * django_linaration_pagination : affichage de listes paginées
250 79 Etienne Pallier
   * django_sorting : affichage de tableaux triables
251 79 Etienne Pallier
   * django_breadcrumbs : création de fil d'ariane
252 79 Etienne Pallier
   * django_xworkflows : gestion de workflows
253 79 Etienne Pallier
   * easy_thumbnails : gestion de miniatures pour les images
254 38 Etienne Pallier
255 81 Etienne Pallier
  * Coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style
256 82 Etienne Pallier
257 1 Etienne Pallier
  * Doc : *https://docs.djangoproject.com/fr (EN FRANCAIS)*
258 82 Etienne Pallier
259 82 Etienne Pallier
   * https://docs.djangoproject.com (EN)
260 72 Etienne Pallier
   * http://www.django-fr.org/planete
261 72 Etienne Pallier
   * https://docs.djangoproject.com/en/1.9/howto/deployment
262 72 Etienne Pallier
   * test fixtures : https://docs.djangoproject.com/en/1.9/howto/initial-data/
263 72 Etienne Pallier
   * managing static files: https://docs.djangoproject.com/en/1.9/howto/static-files/
264 72 Etienne Pallier
   * deploying static files: https://docs.djangoproject.com/en/1.9/howto/static-files/deployment/
265 72 Etienne Pallier
   * install on Windows: https://docs.djangoproject.com/en/1.9/howto/windows/
266 72 Etienne Pallier
   * writing migrations: https://docs.djangoproject.com/en/1.9/howto/writing-migrations/
267 72 Etienne Pallier
   * migrations : https://docs.djangoproject.com/en/1.9/topics/migrations/
268 1 Etienne Pallier
   * Django settings: https://docs.djangoproject.com/en/1.9/topics/settings/
269 72 Etienne Pallier
   * Testing: https://docs.djangoproject.com/en/1.9/topics/testing/
270 72 Etienne Pallier
   * User authentication: https://docs.djangoproject.com/en/1.9/topics/auth/
271 82 Etienne Pallier
272 82 Etienne Pallier
  * Autres ressources:
273 82 Etienne Pallier
274 82 Etienne Pallier
   * django-admin command: https://docs.djangoproject.com/en/1.9/ref/django-admin
275 82 Etienne Pallier
   * http://stackoverflow.com/questions/tagged/django
276 82 Etienne Pallier
   * https://www.djangopackages.com/
277 82 Etienne Pallier
   * http://forum.django-fr.org
278 44 Etienne Pallier
   * La mailing list : django@lists.afpy.org
279 44 Etienne Pallier
280 72 Etienne Pallier
281 4 Etienne Pallier
 * Image processing with Python : https://pillow.readthedocs.org/en/latest/handbook/overview.html
282 4 Etienne Pallier
283 19 Etienne Pallier
 * Git docs: 
284 4 Etienne Pallier
285 131 Etienne Pallier
  * From svn: https://git-scm.com/course/svn.html
286 4 Etienne Pallier
  * Permissions gitlab: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md
287 4 Etienne Pallier
  * https://git-scm.com/docs
288 4 Etienne Pallier
  * https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants
289 15 Etienne Pallier
  * les workflows: https://aresu.dsi.cnrs.fr/spip.php?article219
290 4 Etienne Pallier
  * Git for Eclipse users : http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
291 4 Etienne Pallier
  * Git sur sourcesup (avec jenkins) : https://services.renater.fr/sourcesup/formation/chap04#gestion_d_un_projet_avec_git_jenkins_sonar_et_nexus
292 4 Etienne Pallier
293 4 Etienne Pallier
 * CADOR web interface: http://cador.obs-hp.fr/ros/manual/cador_actions.html
294 4 Etienne Pallier
295 4 Etienne Pallier
 * pylint (analyse de code) : https://www.pylint.org
296 4 Etienne Pallier
297 4 Etienne Pallier
 * pyreverse (uml diagrams generation, inclus dans pylint) : https://www.logilab.org/blogentry/6883
298 4 Etienne Pallier
299 4 Etienne Pallier
 * tox (a generic virtualenv management and test command line tool) : https://testrun.org/tox/latest/index.html
300 5 Etienne Pallier
301 5 Etienne Pallier
---
302 5 Etienne Pallier
303 5 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}I - DATABASE SCHEMA (v0.2.1)%
304 5 Etienne Pallier
305 6 Etienne Pallier
306 7 Etienne Pallier
{{thumbnail(PYROS_PDM_v021.png, size=300, title=Pyros data model)}}
307 6 Etienne Pallier
308 7 Etienne Pallier
---
309 6 Etienne Pallier
310 20 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}II - Get the project (from gitlab)%
311 20 Etienne Pallier
312 20 Etienne Pallier
h3. Gitlab management interface
313 20 Etienne Pallier
314 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros
315 20 Etienne Pallier
316 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros/team
317 6 Etienne Pallier
318 8 Etienne Pallier
h3. Get the project
319 8 Etienne Pallier
320 7 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#II-Get-the-project-from-gitlab
321 7 Etienne Pallier
322 11 Etienne Pallier
---
323 11 Etienne Pallier
324 11 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}III - INSTALLATION%
325 11 Etienne Pallier
326 11 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#III-INSTALLATION
327 11 Etienne Pallier
328 6 Etienne Pallier
---
329 6 Etienne Pallier
330 6 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}IV - CONFIGURATION of the Django Back Office (administration interface)%
331 6 Etienne Pallier
332 9 Etienne Pallier
[[django_backoffice_config|Configuration of the Django Back office (admin)]]
333 9 Etienne Pallier
334 13 Etienne Pallier
---
335 43 Etienne Pallier
336 1 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}V - EVOLUTION OF THE PROJECT%
337 43 Etienne Pallier
338 43 Etienne Pallier
339 43 Etienne Pallier
340 43 Etienne Pallier
h3. Linking the User model to the django's one
341 43 Etienne Pallier
342 43 Etienne Pallier
* Modifications in models.py :
343 43 Etienne Pallier
344 43 Etienne Pallier
    * Rename User model to PyrosUser
345 43 Etienne Pallier
    * Rename user table name to pyros_user
346 43 Etienne Pallier
    * Change all occurences (User -> PyrosUser, users -> pyros_users, ...)
347 43 Etienne Pallier
    * from django.contrib.auth.models import User <== add at the beginning of the file
348 43 Etienne Pallier
    * user = models.OneToOneField(User, on_delete=models.CASCADE) <== add this field in PyrosUser declaration
349 43 Etienne Pallier
    * delete fields in PyrosUser : name, firstname, email, login, pass
350 43 Etienne Pallier
351 43 Etienne Pallier
* Modifications in admin.py :
352 43 Etienne Pallier
353 43 Etienne Pallier
    * Change all occurences (User* -> PyrosUser*, users -> pyros_users, ...)
354 43 Etienne Pallier
355 43 Etienne Pallier
<pre>
356 43 Etienne Pallier
$ python manage.py makemigrations pyrosapp
357 43 Etienne Pallier
$ python manage.py migrate
358 43 Etienne Pallier
</pre>
359 43 Etienne Pallier
360 43 Etienne Pallier
---
361 43 Etienne Pallier
362 41 Etienne Pallier
h3. Manage static files (for admin but also for each application)
363 41 Etienne Pallier
364 41 Etienne Pallier
./manage.py runserver
365 41 Etienne Pallier
366 41 Etienne Pallier
if DEBUG=False, we have errors, missing static files :
367 41 Etienne Pallier
368 41 Etienne Pallier
<pre>
369 41 Etienne Pallier
Not Found: /static/admin/css/base.css
370 41 Etienne Pallier
Not Found: /static/admin/css/login.css
371 41 Etienne Pallier
Not Found: /admin/login
372 41 Etienne Pallier
Not Found: /static/admin/css/base.css
373 41 Etienne Pallier
Not Found: /static/admin/css/login.css
374 41 Etienne Pallier
Not Found: /static/admin/css/base.css
375 41 Etienne Pallier
Not Found: /static/admin/css/login.css
376 41 Etienne Pallier
Not Found: /static/admin/css/base.css
377 41 Etienne Pallier
Not Found: /static/admin/css/dashboard.css
378 41 Etienne Pallier
Not Found: /static/admin/css/base.css
379 41 Etienne Pallier
Not Found: /static/admin/css/base.css
380 41 Etienne Pallier
381 41 Etienne Pallier
</pre>
382 41 Etienne Pallier
383 41 Etienne Pallier
384 41 Etienne Pallier
=> We have to activate the static files management
385 41 Etienne Pallier
386 41 Etienne Pallier
(see https://docs.djangoproject.com/en/1.9/howto/static-files)
387 41 Etienne Pallier
388 41 Etienne Pallier
In pyros/urls.py, add this:
389 41 Etienne Pallier
<pre>
390 41 Etienne Pallier
391 41 Etienne Pallier
from django.conf import settings
392 41 Etienne Pallier
from django.conf.urls.static import static
393 41 Etienne Pallier
394 41 Etienne Pallier
urlpatterns = [
395 41 Etienne Pallier
    url(r'^admin/', admin.site.urls),
396 41 Etienne Pallier
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
397 41 Etienne Pallier
</pre>
398 41 Etienne Pallier
399 41 Etienne Pallier
STATIC_ROOT must be defined in settings and says where is the root of all static files
400 41 Etienne Pallier
401 41 Etienne Pallier
Edit settings.py, add:
402 41 Etienne Pallier
<pre>
403 41 Etienne Pallier
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'public', 'static')
404 41 Etienne Pallier
</pre>
405 41 Etienne Pallier
406 41 Etienne Pallier
407 41 Etienne Pallier
./manage.py collectstatic
408 41 Etienne Pallier
409 41 Etienne Pallier
=> 56 static files copied to '.../PYROS/public/static'
410 41 Etienne Pallier
411 41 Etienne Pallier
(in fact it is in public/static/admin/)
412 41 Etienne Pallier
413 41 Etienne Pallier
Cette commande copie tous les fichiers statiques de toutes les applis
414 41 Etienne Pallier
dans public/static
415 41 Etienne Pallier
416 41 Etienne Pallier
Apache viendra lire ce dossier unique
417 41 Etienne Pallier
418 41 Etienne Pallier
A chq changement d’un fichier statique d’une appli, exécuter « collectstatic » pour mettre à jour le dossier final public/static (auquel on ne doit pas toucher manuellement, c’est un dossier « final »)
419 41 Etienne Pallier
420 39 Etienne Pallier
421 39 Etienne Pallier
---
422 45 Etienne Pallier
423 45 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}DJANGO SHELL (top cool)%
424 51 Etienne Pallier
425 51 Etienne Pallier
cf page 60 for the ORM methods
426 45 Etienne Pallier
427 45 Etienne Pallier
<pre>
428 45 Etienne Pallier
./manage.py shell
429 45 Etienne Pallier
Python 3.5.1 (default, Mar  2 2016, 03:38:02) 
430 46 Etienne Pallier
(InteractiveConsole)
431 45 Etienne Pallier
432 46 Etienne Pallier
>>> import django
433 45 Etienne Pallier
434 46 Etienne Pallier
>>> from pyrosapp.models import *
435 45 Etienne Pallier
436 45 Etienne Pallier
>>> country = Country(name='mexico', quota=1)
437 50 Etienne Pallier
>>> country.save()
438 50 Etienne Pallier
(ajout si pas d’id, modif si id)
439 45 Etienne Pallier
440 45 Etienne Pallier
>>> country = Country(name='france')
441 45 Etienne Pallier
>>> country.save()
442 45 Etienne Pallier
>>> country.pk
443 45 Etienne Pallier
>>> 2
444 45 Etienne Pallier
445 45 Etienne Pallier
>>> countries = Country.objects.all()
446 45 Etienne Pallier
>>> countries.count
447 45 Etienne Pallier
>>> <bound method QuerySet.count of <Country: mexico>, <Country: france>>
448 45 Etienne Pallier
>>> countries.count()
449 45 Etienne Pallier
>>> 2
450 45 Etienne Pallier
>>> print(countries)
451 45 Etienne Pallier
>>> <Country: mexico>, <Country: france>
452 45 Etienne Pallier
>>> print(countries.query)
453 45 Etienne Pallier
>>> SELECT country.id, country.name, country.desc, country.quota FROM country
454 45 Etienne Pallier
455 45 Etienne Pallier
>>> cs = countries.filter(name__icontains='fran')
456 45 Etienne Pallier
>>> print(cs)
457 45 Etienne Pallier
>>> <Country: france>
458 45 Etienne Pallier
459 45 Etienne Pallier
>>> cs = countries.filter(name__startswith='me')
460 45 Etienne Pallier
>>> print(cs)
461 45 Etienne Pallier
>>> <Country: mexico>
462 45 Etienne Pallier
463 45 Etienne Pallier
</pre>
464 45 Etienne Pallier
465 45 Etienne Pallier
466 45 Etienne Pallier
---
467 47 Etienne Pallier
468 47 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}HOWTO (divers)%
469 64 Etienne Pallier
470 1 Etienne Pallier
h3. Models
471 64 Etienne Pallier
472 1 Etienne Pallier
1) Relationships between models (1-1, 1-N, N-M) (p55)
473 61 Etienne Pallier
474 61 Etienne Pallier
models.ManyToManyField : représente une relation de type N-N
475 1 Etienne Pallier
(peu importe de quel côté on le déclare)
476 61 Etienne Pallier
477 48 Etienne Pallier
models.OneToOneField : attention, le sens est important, on n’accèdera d’une table à l’autre que dans un sens
478 61 Etienne Pallier
479 61 Etienne Pallier
task <=> user
480 1 Etienne Pallier
task.user
481 64 Etienne Pallier
user.task_set
482 64 Etienne Pallier
483 64 Etienne Pallier
2) Quelques options pour les champs
484 64 Etienne Pallier
485 64 Etienne Pallier
Chaque type de champ possède ses propres propriétés. Cependant, certaines sont communes et souvent utilisées comme :
486 64 Etienne Pallier
487 64 Etienne Pallier
    verbose_name: label du champ
488 64 Etienne Pallier
    null : valeur NULL autorisée ou non en base de données
489 64 Etienne Pallier
    blank : valeur vide autorisée lors de la validation du champ dans un formulaire
490 64 Etienne Pallier
    default : valeur par défaut pour une nouvelle instance
491 64 Etienne Pallier
    editable : le champ doit-il apparaître automatiquement dans les formulaires
492 64 Etienne Pallier
    ...
493 64 Etienne Pallier
494 64 Etienne Pallier
495 47 Etienne Pallier
496 47 Etienne Pallier
497 47 Etienne Pallier
h3. Pour relier une appli python pure à un projet django :
498 47 Etienne Pallier
499 47 Etienne Pallier
=> Ajouter le src/ dans le pythonpath
500 47 Etienne Pallier
501 47 Etienne Pallier
502 47 Etienne Pallier
h3. Séparer le code métier :
503 47 Etienne Pallier
504 47 Etienne Pallier
=> installer le code métier comme un module via pip
505 47 Etienne Pallier
Couches :
506 47 Etienne Pallier
* présentation
507 47 Etienne Pallier
* métier
508 47 Etienne Pallier
* modèle
509 49 Etienne Pallier
510 49 Etienne Pallier
h3. ORM
511 49 Etienne Pallier
512 49 Etienne Pallier
(cf page 60)
513 59 Etienne Pallier
514 73 Etienne Pallier
<pre>
515 161 Etienne Pallier
516 161 Etienne Pallier
Exemple: Book
517 161 Etienne Pallier
===========================
518 161 Etienne Pallier
519 73 Etienne Pallier
b = Book(name='Two scoops of django',
520 1 Etienne Pallier
             release=date(2013, 08, 31))
521 73 Etienne Pallier
b.save()
522 73 Etienne Pallier
=> ajout car pas d’id, 
523 74 Etienne Pallier
524 74 Etienne Pallier
b.name ='Two scoops of django - Best practices'
525 1 Etienne Pallier
b.save()
526 74 Etienne Pallier
=> modif car il y a un id
527 74 Etienne Pallier
528 1 Etienne Pallier
b.delete()
529 75 Etienne Pallier
530 49 Etienne Pallier
Toutes les instances:
531 49 Etienne Pallier
Book.objects.all()
532 75 Etienne Pallier
533 59 Etienne Pallier
Liste filtrée:
534 49 Etienne Pallier
books = Book.objects.filter(
535 49 Etienne Pallier
        release__gte=date(2013, 01, 01)
536 49 Etienne Pallier
      ).exclude(
537 49 Etienne Pallier
        borrowed=True
538 49 Etienne Pallier
      )
539 1 Etienne Pallier
540 161 Etienne Pallier
Attention, la requete est exécutée le plus tard possible, seulement quand django a vraiment besoin de l’exécuter
541 75 Etienne Pallier
542 49 Etienne Pallier
Liste ordonnée:
543 49 Etienne Pallier
books = Book.objects.exclude(borrowed=True).order_by('title')
544 75 Etienne Pallier
print (books.author)
545 49 Etienne Pallier
546 77 Etienne Pallier
Une instance précise:
547 75 Etienne Pallier
Book.objects.get(pk=12)
548 77 Etienne Pallier
549 1 Etienne Pallier
550 1 Etienne Pallier
551 1 Etienne Pallier
552 162 Etienne Pallier
553 161 Etienne Pallier
Liens vers objets associés:
554 161 Etienne Pallier
===========================
555 161 Etienne Pallier
556 77 Etienne Pallier
Retrouver les livres disponibles d'un auteur :
557 77 Etienne Pallier
>> author = Author.objects.get(pk=25)
558 1 Etienne Pallier
>> author.books.filter(borrowed=False)
559 1 Etienne Pallier
(books est le related name déclaré dans la relation manytomany)
560 77 Etienne Pallier
561 75 Etienne Pallier
562 77 Etienne Pallier
Ajouter un livre à une catégorie :
563 77 Etienne Pallier
>> category = Category.objects.get(pk=5)
564 77 Etienne Pallier
>> book = Book.objects.get(pk=12)
565 75 Etienne Pallier
>> category.books.add(book)
566 75 Etienne Pallier
567 1 Etienne Pallier
Supprimer l'association de livres à une catégorie :
568 1 Etienne Pallier
>> category = Category.objects.get(pk=5)
569 77 Etienne Pallier
>> category.books.clear()
570 161 Etienne Pallier
571 161 Etienne Pallier
</pre>
572 47 Etienne Pallier
573 53 Etienne Pallier
---
574 53 Etienne Pallier
575 53 Etienne Pallier
h3. Serveur Web
576 104 Paul Carensac
577 157 Etienne Pallier
<pre>
578 157 Etienne Pallier
579 104 Paul Carensac
Passer sur le port 80 :
580 104 Paul Carensac
581 104 Paul Carensac
venv_py35_pyros ==> lib ==> python3.5 ==> site-packages ==> django ==> core ==> management ==> commands
582 104 Paul Carensac
Edit runserver.py and change "default_port"
583 104 Paul Carensac
584 53 Etienne Pallier
585 53 Etienne Pallier
Apache : gère tous les fichiers statiques (images, html…), et délègue les fichiers python au serveur django
586 53 Etienne Pallier
587 53 Etienne Pallier
Moteur web django sera soit du wsgi soit du unicorn
588 53 Etienne Pallier
Par défaut, 1 seul worker, mais on peut en configurer plusieurs,
589 53 Etienne Pallier
l’idéal étant de faire nb coeurs + 1 (le worker maître qui fait le dispatching aux autres)
590 53 Etienne Pallier
591 53 Etienne Pallier
Frontend : Apache ou Ngininx
592 53 Etienne Pallier
Backend : gunicorn (gère facilement des workers) ou uwsgi
593 53 Etienne Pallier
594 53 Etienne Pallier
==> gunicorn library.wsgi
595 53 Etienne Pallier
(à la place de manage runserver ==> A EVITER EN PROD)
596 53 Etienne Pallier
597 53 Etienne Pallier
pip install gunicorn
598 53 Etienne Pallier
599 53 Etienne Pallier
gunicorn library.wsgi
600 53 Etienne Pallier
ou
601 53 Etienne Pallier
gunicorn - - workers 5 library.wsgi
602 53 Etienne Pallier
603 156 Etienne Pallier
(gunicorn est un équivalent de tomcat, c'est un serveur d’appli Python)
604 53 Etienne Pallier
605 53 Etienne Pallier
1) URL arrive à Apache, qui dispatche (il gère seul les fichiers statiques, et les fichiers python il les transmet à Django)
606 53 Etienne Pallier
2) le fichier library/urls.py prend le relai pour tout ce qui est django
607 65 Etienne Pallier
608 65 Etienne Pallier
609 65 Etienne Pallier
*On peut ajouter un fichier urls.py pour gérer les urls de l’appli
610 65 Etienne Pallier
(on garde le urls.py général du projet pour gérer les grandes urls):*
611 157 Etienne Pallier
612 157 Etienne Pallier
</pre>
613 157 Etienne Pallier
614 1 Etienne Pallier
615 66 Etienne Pallier
616 66 Etienne Pallier
<pre>
617 65 Etienne Pallier
Déclaration d'une URL
618 65 Etienne Pallier
619 65 Etienne Pallier
# books/urls.py
620 65 Etienne Pallier
from django.conf.urls import patterns, include, url
621 65 Etienne Pallier
urlpatterns = [
622 65 Etienne Pallier
    url(r'^book_list$', 'books.views.book_list', name='book_list'),
623 65 Etienne Pallier
]
624 65 Etienne Pallier
625 65 Etienne Pallier
Inclusion des URLs de l'application au projet
626 65 Etienne Pallier
627 65 Etienne Pallier
# library/urls.py
628 65 Etienne Pallier
...
629 65 Etienne Pallier
urlpatterns = [
630 65 Etienne Pallier
    ...
631 1 Etienne Pallier
    url(r'^books/', include('books.urls', namespace='books')),
632 60 Etienne Pallier
]
633 60 Etienne Pallier
634 60 Etienne Pallier
</pre>
635 60 Etienne Pallier
636 60 Etienne Pallier
h3. MTV design pattern
637 60 Etienne Pallier
638 60 Etienne Pallier
639 60 Etienne Pallier
MTV == MVC :
640 60 Etienne Pallier
641 60 Etienne Pallier
Model = Model
642 60 Etienne Pallier
Template = View
643 60 Etienne Pallier
View = Controller
644 60 Etienne Pallier
645 60 Etienne Pallier
646 60 Etienne Pallier
CREATION DE LA VUE (en fait, le controleur) : slide 23
647 60 Etienne Pallier
views.py = CONTROLEUR
648 60 Etienne Pallier
649 60 Etienne Pallier
650 60 Etienne Pallier
Template = LA VUE (slide 24)
651 60 Etienne Pallier
(on peut user Jinja à la place du moteur django par défaut)
652 60 Etienne Pallier
653 60 Etienne Pallier
Dans chq appli, on crée un dossier templates/ et un sous-dossier du nom de l’appli/
654 60 Etienne Pallier
(==> todo/templates/todo/)
655 60 Etienne Pallier
656 60 Etienne Pallier
Même principe pour les fichiers statiques :
657 60 Etienne Pallier
src/static/appli1, appli2, appli3…
658 60 Etienne Pallier
659 60 Etienne Pallier
NOMENCLATURE template :
660 60 Etienne Pallier
nommodèle_action.html
661 60 Etienne Pallier
(ex: book_list.html)
662 60 Etienne Pallier
663 60 Etienne Pallier
*On pourrait tout mettre dans le urls.py du projet, MAIS c’est mieux
664 60 Etienne Pallier
de créer un fichier urls.py PAR APPLI, puis de les inclure dans le fichier urls.py principal*
665 60 Etienne Pallier
666 60 Etienne Pallier
Class-based views ==> classes controleurs
667 60 Etienne Pallier
Les méthodes get() et post() sont déjà définies, et on peut les surcharger…
668 60 Etienne Pallier
669 60 Etienne Pallier
Avec un template (gabarit), on peut générer autre chose que du html,
670 60 Etienne Pallier
on peut par ex générer du texte, du pdf, un email, un xml…
671 60 Etienne Pallier
672 60 Etienne Pallier
673 60 Etienne Pallier
674 60 Etienne Pallier
Vue liste (et détail) :
675 60 Etienne Pallier
https://docs.djangoproject.com/fr/1.8/topics/class-based-views/generic-display/
676 60 Etienne Pallier
1) todo/views.py
677 60 Etienne Pallier
from django.views.generic import ListView
678 60 Etienne Pallier
from books.models import Publisher
679 60 Etienne Pallier
680 60 Etienne Pallier
class PublisherList(ListView):
681 60 Etienne Pallier
    model = Publisher
682 60 Etienne Pallier
683 60 Etienne Pallier
684 60 Etienne Pallier
2) todolist/urls.py
685 60 Etienne Pallier
from django.conf.urls import url
686 60 Etienne Pallier
from books.views import PublisherList
687 60 Etienne Pallier
688 60 Etienne Pallier
urlpatterns = [
689 60 Etienne Pallier
    url(r'^publishers/$', PublisherList.as_view()),
690 60 Etienne Pallier
]
691 60 Etienne Pallier
692 60 Etienne Pallier
3) todo/templates/todo/
693 60 Etienne Pallier
694 60 Etienne Pallier
695 60 Etienne Pallier
696 53 Etienne Pallier
- Vue Liste : par défaut le template reçoit un objet « objects_list »
697 53 Etienne Pallier
- Vue détail : object (on peut faire object.pk, …)
698 53 Etienne Pallier
699 53 Etienne Pallier
700 53 Etienne Pallier
701 40 Etienne Pallier
---
702 87 Etienne Pallier
703 87 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}USEFUL TOOLS FOR DEV%
704 88 Etienne Pallier
705 159 Etienne Pallier
706 159 Etienne Pallier
707 159 Etienne Pallier
708 159 Etienne Pallier
---
709 159 Etienne Pallier
710 159 Etienne Pallier
h3. PlantUML
711 159 Etienne Pallier
712 159 Etienne Pallier
Pour créer des diagrammes UML à la volée, à partir d'un fichier texte, au fur et à mesure de la frappe
713 159 Etienne Pallier
714 159 Etienne Pallier
1) Installer le plugin : Menu Help/Install New Software... 
715 159 Etienne Pallier
716 159 Etienne Pallier
Entrer l'adresse suivante, et sélectionner PlantUML
717 159 Etienne Pallier
718 159 Etienne Pallier
http://plantuml.sourceforge.net/updatesitejuno/
719 159 Etienne Pallier
720 159 Etienne Pallier
721 159 Etienne Pallier
2) Ensuite, il faut aussi installer graphviz :
722 159 Etienne Pallier
723 159 Etienne Pallier
$ sudo apt-get install graphviz
724 159 Etienne Pallier
725 159 Etienne Pallier
(ou $ sudo yum install graphviz)
726 159 Etienne Pallier
727 159 Etienne Pallier
728 159 Etienne Pallier
3) Créer un graphique UML
729 159 Etienne Pallier
730 159 Etienne Pallier
Depuis Eclipse:
731 159 Etienne Pallier
732 159 Etienne Pallier
- Créer un fichier texte (voir exemple ci-dessous)
733 159 Etienne Pallier
734 159 Etienne Pallier
- Window/Show View/Other/Plantuml
735 159 Etienne Pallier
736 159 Etienne Pallier
=> le diagramme doit alors s'afficher
737 159 Etienne Pallier
738 159 Etienne Pallier
739 159 Etienne Pallier
740 159 Etienne Pallier
741 159 Etienne Pallier
742 88 Etienne Pallier
---
743 96 Etienne Pallier
744 95 Etienne Pallier
h3. Pyreverse (included in pylint) : useful for generating uml class diagrams
745 1 Etienne Pallier
746 96 Etienne Pallier
https://www.logilab.org/blogentry/6883
747 96 Etienne Pallier
748 96 Etienne Pallier
<pre>
749 96 Etienne Pallier
$ cd PYROS/
750 96 Etienne Pallier
751 96 Etienne Pallier
$ pyreverse -o png -p pyrosapp -a 1 -A src/pyrosapp/
752 96 Etienne Pallier
753 97 Etienne Pallier
$ pyreverse -o png -p pyrosapp -s 1 -S src/pyrosapp/
754 97 Etienne Pallier
755 96 Etienne Pallier
$ pyreverse -ASmy -k -o png -p pyrosappadmin src/pyrosapp/admin.py
756 1 Etienne Pallier
</pre>
757 99 Etienne Pallier
758 99 Etienne Pallier
{{thumbnail(classes_pyrosapp.png, size=300)}}
759 99 Etienne Pallier
{{thumbnail(classes_pyrosappadmin.png, size=300)}}
760 99 Etienne Pallier
{{thumbnail(classes_dashboard.png, size=300)}}
761 98 Etienne Pallier
762 98 Etienne Pallier
763 89 Etienne Pallier
h3. django-extensions and graphviz : useful for generating an image of all the models and their relationships
764 91 Etienne Pallier
765 89 Etienne Pallier
{{thumbnail(models.png, size=300, title=Pyros data model)}}
766 90 Etienne Pallier
767 89 Etienne Pallier
django-extensions: http://django-extensions.readthedocs.org/en/latest/installation_instructions.html
768 92 Etienne Pallier
769 92 Etienne Pallier
GraphViz (development) installation :
770 92 Etienne Pallier
771 92 Etienne Pallier
<pre>
772 92 Etienne Pallier
MacOS with macport:
773 92 Etienne Pallier
$ sudo port install graphviz-devel
774 92 Etienne Pallier
775 92 Etienne Pallier
Ubuntu:
776 92 Etienne Pallier
$ sudo apt-get install graphviz-dev
777 92 Etienne Pallier
778 92 Etienne Pallier
Windows:
779 92 Etienne Pallier
Download it
780 92 Etienne Pallier
</pre>
781 93 Etienne Pallier
782 1 Etienne Pallier
Python pygraphviz package installation:
783 92 Etienne Pallier
<pre>
784 1 Etienne Pallier
$ pip install pygraphviz
785 1 Etienne Pallier
=> errors on MacOS (using macport) : "fatal error: 'graphviz/cgraph.h' file not found"
786 93 Etienne Pallier
=> $ pip install --install-option="--include-path=/opt/local/include"  --install-option="--library-path=/opt/local/lib" pygraphviz
787 1 Etienne Pallier
</pre>
788 93 Etienne Pallier
789 93 Etienne Pallier
Python django-extensions package installation:
790 93 Etienne Pallier
<pre>
791 93 Etienne Pallier
$ pip install django-bootstrap3
792 93 Etienne Pallier
$ pip install django-extensions
793 93 Etienne Pallier
($ pip install --upgrade django-extensions)
794 92 Etienne Pallier
</pre>
795 93 Etienne Pallier
796 93 Etienne Pallier
Generate the image:
797 93 Etienne Pallier
<pre>
798 92 Etienne Pallier
$ cd src/
799 93 Etienne Pallier
$ python manage.py graph_models -a -g -o models.png
800 92 Etienne Pallier
</pre>
801 89 Etienne Pallier
802 89 Etienne Pallier
---
803 6 Etienne Pallier
804 6 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}INSTALLATION FROM THE BEGINNING (for dev only, history of the initial project creation)%
805 1 Etienne Pallier
806 1 Etienne Pallier
807 1 Etienne Pallier
[[pyros_install_from_start|Pyros installation from the beginning]]