Project Development

Version 69 (Etienne Pallier, 03/29/2016 03:30 pm)

1 1 Etienne Pallier
h1. Project Development
2 2 Etienne Pallier
3 17 Etienne Pallier
Project Installation page : [[Project Installation]]
4 2 Etienne Pallier
5 2 Etienne Pallier
HOWTO Format Redmine Wiki : http://www.redmine.org/projects/redmine/wiki/FrRedmineWikiFormatting
6 2 Etienne Pallier
7 2 Etienne Pallier
{{>toc}}
8 2 Etienne Pallier
9 2 Etienne Pallier
---
10 3 Etienne Pallier
11 3 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}TODO%
12 3 Etienne Pallier
13 1 Etienne Pallier
14 1 Etienne Pallier
15 69 Etienne Pallier
 
16 29 Etienne Pallier
 * readonly admin interface : https://gist.github.com/aaugustin/1388243
17 35 Etienne Pallier
18 3 Etienne Pallier
19 3 Etienne Pallier
20 3 Etienne Pallier
 * Planifier la suite...
21 57 Etienne Pallier
22 57 Etienne Pallier
23 56 Etienne Pallier
24 24 Etienne Pallier
 * pyrossu : pyrossu!
25 3 Etienne Pallier
26 4 Etienne Pallier
---
27 4 Etienne Pallier
28 4 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}LIENS UTILES%
29 4 Etienne Pallier
30 4 Etienne Pallier
 * Liens vers web local :
31 4 Etienne Pallier
32 4 Etienne Pallier
  * homepage: http://localhost:8000
33 4 Etienne Pallier
  * admin: http://localhost:8000/admin
34 25 Etienne Pallier
35 25 Etienne Pallier
 * Eclipse:
36 26 Etienne Pallier
 
37 26 Etienne Pallier
  * Shift-Ctrl-f (ou Shift-Cmd-f) : reformatage du fichier selon PEP8
38 25 Etienne Pallier
  * Shift-Ctrl-1 : make doc string ...
39 4 Etienne Pallier
40 4 Etienne Pallier
 * Django:
41 4 Etienne Pallier
42 38 Etienne Pallier
  * Coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style
43 38 Etienne Pallier
  * Doc : https://docs.djangoproject.com/en/1.9
44 44 Etienne Pallier
  * (FR) http://docs.djangoproject.com/fr
45 44 Etienne Pallier
  * http://stackoverflow.com/questions/tagged/django
46 44 Etienne Pallier
  * www.django-fr.org/planete
47 44 Etienne Pallier
  * https://www.djangopackages.com/
48 44 Etienne Pallier
  * http://forum.django-fr.org
49 44 Etienne Pallier
  * La mailing list : django@lists.afpy.org
50 44 Etienne Pallier
51 44 Etienne Pallier
52 4 Etienne Pallier
53 4 Etienne Pallier
 * Git docs: 
54 19 Etienne Pallier
55 4 Etienne Pallier
  * Permissions gitlab: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md
56 4 Etienne Pallier
  * https://git-scm.com/docs
57 4 Etienne Pallier
  * https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants
58 4 Etienne Pallier
  * les workflows: https://aresu.dsi.cnrs.fr/spip.php?article219
59 15 Etienne Pallier
  * Git for Eclipse users : http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
60 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
61 4 Etienne Pallier
62 4 Etienne Pallier
 * CADOR web interface: http://cador.obs-hp.fr/ros/manual/cador_actions.html
63 4 Etienne Pallier
64 4 Etienne Pallier
 * pylint (analyse de code) : https://www.pylint.org
65 4 Etienne Pallier
66 4 Etienne Pallier
 * pyreverse (uml diagrams generation, inclus dans pylint) : https://www.logilab.org/blogentry/6883
67 4 Etienne Pallier
68 4 Etienne Pallier
 * tox (a generic virtualenv management and test command line tool) : https://testrun.org/tox/latest/index.html
69 4 Etienne Pallier
70 5 Etienne Pallier
---
71 5 Etienne Pallier
72 5 Etienne Pallier
73 5 Etienne Pallier
---
74 5 Etienne Pallier
75 5 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}I - DATABASE SCHEMA (v0.2.1)%
76 5 Etienne Pallier
77 5 Etienne Pallier
78 6 Etienne Pallier
{{thumbnail(PYROS_PDM_v021.png, size=300, title=Pyros data model)}}
79 7 Etienne Pallier
80 6 Etienne Pallier
---
81 7 Etienne Pallier
82 6 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}II - Get the project (from gitlab)%
83 20 Etienne Pallier
84 20 Etienne Pallier
h3. Gitlab management interface
85 20 Etienne Pallier
86 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros
87 20 Etienne Pallier
88 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros/team
89 20 Etienne Pallier
90 6 Etienne Pallier
h3. Get the project
91 8 Etienne Pallier
92 8 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#II-Get-the-project-from-gitlab
93 7 Etienne Pallier
94 7 Etienne Pallier
---
95 11 Etienne Pallier
96 11 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}III - INSTALLATION%
97 11 Etienne Pallier
98 11 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#III-INSTALLATION
99 11 Etienne Pallier
100 11 Etienne Pallier
---
101 6 Etienne Pallier
102 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)%
103 6 Etienne Pallier
104 6 Etienne Pallier
[[django_backoffice_config|Configuration of the Django Back office (admin)]]
105 9 Etienne Pallier
106 9 Etienne Pallier
---
107 13 Etienne Pallier
108 43 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}V - EVOLUTION OF THE PROJECT%
109 1 Etienne Pallier
110 43 Etienne Pallier
111 43 Etienne Pallier
112 43 Etienne Pallier
h3. Linking the User model to the django's one
113 43 Etienne Pallier
114 43 Etienne Pallier
* Modifications in models.py :
115 43 Etienne Pallier
116 43 Etienne Pallier
    * Rename User model to PyrosUser
117 43 Etienne Pallier
    * Rename user table name to pyros_user
118 43 Etienne Pallier
    * Change all occurences (User -> PyrosUser, users -> pyros_users, ...)
119 43 Etienne Pallier
    * from django.contrib.auth.models import User <== add at the beginning of the file
120 43 Etienne Pallier
    * user = models.OneToOneField(User, on_delete=models.CASCADE) <== add this field in PyrosUser declaration
121 43 Etienne Pallier
    * delete fields in PyrosUser : name, firstname, email, login, pass
122 43 Etienne Pallier
123 43 Etienne Pallier
* Modifications in admin.py :
124 43 Etienne Pallier
125 43 Etienne Pallier
    * Change all occurences (User* -> PyrosUser*, users -> pyros_users, ...)
126 43 Etienne Pallier
127 43 Etienne Pallier
<pre>
128 43 Etienne Pallier
$ python manage.py makemigrations pyrosapp
129 43 Etienne Pallier
$ python manage.py migrate
130 43 Etienne Pallier
</pre>
131 43 Etienne Pallier
132 43 Etienne Pallier
---
133 43 Etienne Pallier
134 43 Etienne Pallier
h3. Manage static files (for admin but also for each application)
135 41 Etienne Pallier
136 41 Etienne Pallier
./manage.py runserver
137 41 Etienne Pallier
138 41 Etienne Pallier
if DEBUG=False, we have errors, missing static files :
139 41 Etienne Pallier
140 41 Etienne Pallier
<pre>
141 41 Etienne Pallier
Not Found: /static/admin/css/base.css
142 41 Etienne Pallier
Not Found: /static/admin/css/login.css
143 41 Etienne Pallier
Not Found: /admin/login
144 41 Etienne Pallier
Not Found: /static/admin/css/base.css
145 41 Etienne Pallier
Not Found: /static/admin/css/login.css
146 41 Etienne Pallier
Not Found: /static/admin/css/base.css
147 41 Etienne Pallier
Not Found: /static/admin/css/login.css
148 41 Etienne Pallier
Not Found: /static/admin/css/base.css
149 41 Etienne Pallier
Not Found: /static/admin/css/dashboard.css
150 41 Etienne Pallier
Not Found: /static/admin/css/base.css
151 41 Etienne Pallier
Not Found: /static/admin/css/base.css
152 41 Etienne Pallier
153 41 Etienne Pallier
</pre>
154 41 Etienne Pallier
155 41 Etienne Pallier
156 41 Etienne Pallier
=> We have to activate the static files management
157 41 Etienne Pallier
158 41 Etienne Pallier
(see https://docs.djangoproject.com/en/1.9/howto/static-files)
159 41 Etienne Pallier
160 41 Etienne Pallier
In pyros/urls.py, add this:
161 41 Etienne Pallier
<pre>
162 41 Etienne Pallier
163 41 Etienne Pallier
from django.conf import settings
164 41 Etienne Pallier
from django.conf.urls.static import static
165 41 Etienne Pallier
166 41 Etienne Pallier
urlpatterns = [
167 41 Etienne Pallier
    url(r'^admin/', admin.site.urls),
168 41 Etienne Pallier
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
169 41 Etienne Pallier
</pre>
170 41 Etienne Pallier
171 41 Etienne Pallier
STATIC_ROOT must be defined in settings and says where is the root of all static files
172 41 Etienne Pallier
173 41 Etienne Pallier
Edit settings.py, add:
174 41 Etienne Pallier
<pre>
175 41 Etienne Pallier
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'public', 'static')
176 41 Etienne Pallier
</pre>
177 41 Etienne Pallier
178 41 Etienne Pallier
179 41 Etienne Pallier
./manage.py collectstatic
180 41 Etienne Pallier
181 41 Etienne Pallier
=> 56 static files copied to '.../PYROS/public/static'
182 41 Etienne Pallier
183 41 Etienne Pallier
(in fact it is in public/static/admin/)
184 41 Etienne Pallier
185 41 Etienne Pallier
Cette commande copie tous les fichiers statiques de toutes les applis
186 41 Etienne Pallier
dans public/static
187 41 Etienne Pallier
188 41 Etienne Pallier
Apache viendra lire ce dossier unique
189 41 Etienne Pallier
190 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 »)
191 41 Etienne Pallier
192 41 Etienne Pallier
193 39 Etienne Pallier
---
194 39 Etienne Pallier
195 45 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}DJANGO SHELL (top cool)%
196 45 Etienne Pallier
197 51 Etienne Pallier
cf page 60 for the ORM methods
198 51 Etienne Pallier
199 45 Etienne Pallier
<pre>
200 45 Etienne Pallier
./manage.py shell
201 45 Etienne Pallier
Python 3.5.1 (default, Mar  2 2016, 03:38:02) 
202 45 Etienne Pallier
(InteractiveConsole)
203 46 Etienne Pallier
204 45 Etienne Pallier
>>> import django
205 46 Etienne Pallier
206 45 Etienne Pallier
>>> from pyrosapp.models import *
207 46 Etienne Pallier
208 45 Etienne Pallier
>>> country = Country(name='mexico', quota=1)
209 45 Etienne Pallier
>>> country.save()
210 50 Etienne Pallier
(ajout si pas d’id, modif si id)
211 50 Etienne Pallier
212 45 Etienne Pallier
>>> country = Country(name='france')
213 45 Etienne Pallier
>>> country.save()
214 45 Etienne Pallier
>>> country.pk
215 45 Etienne Pallier
>>> 2
216 45 Etienne Pallier
217 45 Etienne Pallier
>>> countries = Country.objects.all()
218 45 Etienne Pallier
>>> countries.count
219 45 Etienne Pallier
>>> <bound method QuerySet.count of <Country: mexico>, <Country: france>>
220 45 Etienne Pallier
>>> countries.count()
221 45 Etienne Pallier
>>> 2
222 45 Etienne Pallier
>>> print(countries)
223 45 Etienne Pallier
>>> <Country: mexico>, <Country: france>
224 45 Etienne Pallier
>>> print(countries.query)
225 45 Etienne Pallier
>>> SELECT country.id, country.name, country.desc, country.quota FROM country
226 45 Etienne Pallier
227 45 Etienne Pallier
>>> cs = countries.filter(name__icontains='fran')
228 45 Etienne Pallier
>>> print(cs)
229 45 Etienne Pallier
>>> <Country: france>
230 45 Etienne Pallier
231 45 Etienne Pallier
>>> cs = countries.filter(name__startswith='me')
232 45 Etienne Pallier
>>> print(cs)
233 45 Etienne Pallier
>>> <Country: mexico>
234 45 Etienne Pallier
235 45 Etienne Pallier
</pre>
236 45 Etienne Pallier
237 45 Etienne Pallier
238 45 Etienne Pallier
---
239 45 Etienne Pallier
240 47 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}HOWTO (divers)%
241 47 Etienne Pallier
242 64 Etienne Pallier
h3. Models
243 1 Etienne Pallier
244 64 Etienne Pallier
1) Relationships between models (1-1, 1-N, N-M) (p55)
245 1 Etienne Pallier
246 61 Etienne Pallier
models.ManyToManyField : représente une relation de type N-N
247 61 Etienne Pallier
(peu importe de quel côté on le déclare)
248 1 Etienne Pallier
249 61 Etienne Pallier
models.OneToOneField : attention, le sens est important, on n’accèdera d’une table à l’autre que dans un sens
250 48 Etienne Pallier
251 61 Etienne Pallier
task <=> user
252 61 Etienne Pallier
task.user
253 1 Etienne Pallier
user.task_set
254 64 Etienne Pallier
255 64 Etienne Pallier
2) Quelques options pour les champs
256 64 Etienne Pallier
257 64 Etienne Pallier
Chaque type de champ possède ses propres propriétés. Cependant, certaines sont communes et souvent utilisées comme :
258 64 Etienne Pallier
259 64 Etienne Pallier
    verbose_name: label du champ
260 64 Etienne Pallier
    null : valeur NULL autorisée ou non en base de données
261 64 Etienne Pallier
    blank : valeur vide autorisée lors de la validation du champ dans un formulaire
262 64 Etienne Pallier
    default : valeur par défaut pour une nouvelle instance
263 64 Etienne Pallier
    editable : le champ doit-il apparaître automatiquement dans les formulaires
264 64 Etienne Pallier
    ...
265 64 Etienne Pallier
266 64 Etienne Pallier
267 64 Etienne Pallier
268 47 Etienne Pallier
269 47 Etienne Pallier
h3. Pour relier une appli python pure à un projet django :
270 47 Etienne Pallier
271 47 Etienne Pallier
=> Ajouter le src/ dans le pythonpath
272 47 Etienne Pallier
273 47 Etienne Pallier
274 47 Etienne Pallier
h3. Séparer le code métier :
275 47 Etienne Pallier
276 47 Etienne Pallier
=> installer le code métier comme un module via pip
277 47 Etienne Pallier
Couches :
278 47 Etienne Pallier
* présentation
279 47 Etienne Pallier
* métier
280 47 Etienne Pallier
* modèle
281 47 Etienne Pallier
282 49 Etienne Pallier
h3. ORM
283 49 Etienne Pallier
284 49 Etienne Pallier
(cf page 60)
285 49 Etienne Pallier
286 59 Etienne Pallier
<pre>
287 1 Etienne Pallier
b = Book(…)
288 59 Etienne Pallier
b.save()
289 59 Etienne Pallier
=> ajout si pas d’id, modif si id
290 1 Etienne Pallier
291 49 Etienne Pallier
Book.objects.all()
292 49 Etienne Pallier
293 59 Etienne Pallier
books = Book.objects.filter(
294 49 Etienne Pallier
        release__gte=date(2013, 01, 01)
295 49 Etienne Pallier
      ).exclude(
296 49 Etienne Pallier
        borrowed=True
297 49 Etienne Pallier
      )
298 49 Etienne Pallier
299 49 Etienne Pallier
A! La requete est exécutée le plus tard possible, seulement quand django a vraiment besoin de l’exécuter
300 49 Etienne Pallier
301 49 Etienne Pallier
books = Book.objects.exclude(borrowed=True).order_by('title')
302 49 Etienne Pallier
print (books.author)
303 49 Etienne Pallier
304 49 Etienne Pallier
Book.objects.get(pk=12)
305 49 Etienne Pallier
306 1 Etienne Pallier
author = Author.objects.get(pk=25)
307 49 Etienne Pallier
author.books.filter(borrowed=False)
308 49 Etienne Pallier
309 49 Etienne Pallier
(books est le related name déclaré dans la relation manytomany)
310 59 Etienne Pallier
</pre>
311 47 Etienne Pallier
312 47 Etienne Pallier
---
313 47 Etienne Pallier
314 53 Etienne Pallier
h3. Serveur Web
315 53 Etienne Pallier
316 53 Etienne Pallier
Apache : gère tous les fichiers statiques (images, html…), et délègue les fichiers python au serveur django
317 53 Etienne Pallier
318 53 Etienne Pallier
Moteur web django sera soit du wsgi soit du unicorn
319 53 Etienne Pallier
Par défaut, 1 seul worker, mais on peut en configurer plusieurs,
320 53 Etienne Pallier
l’idéal étant de faire nb coeurs + 1 (le worker maître qui fait le dispatching aux autres)
321 53 Etienne Pallier
322 53 Etienne Pallier
Frontend : Apache ou Ngininx
323 53 Etienne Pallier
Backend : gunicorn (gère facilement des workers) ou uwsgi
324 53 Etienne Pallier
325 53 Etienne Pallier
==> gunicorn library.wsgi
326 53 Etienne Pallier
(à la place de manage runserver ==> A EVITER EN PROD)
327 53 Etienne Pallier
328 53 Etienne Pallier
pip install gunicorn
329 53 Etienne Pallier
330 53 Etienne Pallier
gunicorn library.wsgi
331 53 Etienne Pallier
ou
332 53 Etienne Pallier
gunicorn - - workers 5 library.wsgi
333 53 Etienne Pallier
334 53 Etienne Pallier
(gunicorn == tomcat, serveur d’appli Python)
335 53 Etienne Pallier
336 53 Etienne Pallier
1) URL arrive à Apache, qui dispatche (il gère seul les fichiers statiques, et les fichiers python il les transmet à Django)
337 53 Etienne Pallier
2) le fichier library/urls.py prend le relai pour tout ce qui est django
338 53 Etienne Pallier
339 53 Etienne Pallier
340 65 Etienne Pallier
*On peut ajouter un fichier urls.py pour gérer les urls de l’appli
341 65 Etienne Pallier
(on garde le urls.py général du projet pour gérer les grandes urls):*
342 65 Etienne Pallier
343 65 Etienne Pallier
344 1 Etienne Pallier
<pre>
345 66 Etienne Pallier
Déclaration d'une URL
346 66 Etienne Pallier
347 65 Etienne Pallier
# books/urls.py
348 65 Etienne Pallier
from django.conf.urls import patterns, include, url
349 65 Etienne Pallier
urlpatterns = [
350 65 Etienne Pallier
    url(r'^book_list$', 'books.views.book_list', name='book_list'),
351 65 Etienne Pallier
]
352 65 Etienne Pallier
353 65 Etienne Pallier
Inclusion des URLs de l'application au projet
354 65 Etienne Pallier
355 65 Etienne Pallier
# library/urls.py
356 65 Etienne Pallier
...
357 65 Etienne Pallier
urlpatterns = [
358 65 Etienne Pallier
    ...
359 65 Etienne Pallier
    url(r'^books/', include('books.urls', namespace='books')),
360 65 Etienne Pallier
]
361 1 Etienne Pallier
362 60 Etienne Pallier
</pre>
363 60 Etienne Pallier
364 60 Etienne Pallier
h3. MTV design pattern
365 60 Etienne Pallier
366 60 Etienne Pallier
367 60 Etienne Pallier
MTV == MVC :
368 60 Etienne Pallier
369 60 Etienne Pallier
Model = Model
370 60 Etienne Pallier
Template = View
371 60 Etienne Pallier
View = Controller
372 60 Etienne Pallier
373 60 Etienne Pallier
374 60 Etienne Pallier
CREATION DE LA VUE (en fait, le controleur) : slide 23
375 60 Etienne Pallier
views.py = CONTROLEUR
376 60 Etienne Pallier
377 60 Etienne Pallier
378 60 Etienne Pallier
Template = LA VUE (slide 24)
379 60 Etienne Pallier
(on peut user Jinja à la place du moteur django par défaut)
380 60 Etienne Pallier
381 60 Etienne Pallier
Dans chq appli, on crée un dossier templates/ et un sous-dossier du nom de l’appli/
382 60 Etienne Pallier
(==> todo/templates/todo/)
383 60 Etienne Pallier
384 60 Etienne Pallier
Même principe pour les fichiers statiques :
385 60 Etienne Pallier
src/static/appli1, appli2, appli3…
386 60 Etienne Pallier
387 60 Etienne Pallier
NOMENCLATURE template :
388 60 Etienne Pallier
nommodèle_action.html
389 60 Etienne Pallier
(ex: book_list.html)
390 60 Etienne Pallier
391 60 Etienne Pallier
*On pourrait tout mettre dans le urls.py du projet, MAIS c’est mieux
392 60 Etienne Pallier
de créer un fichier urls.py PAR APPLI, puis de les inclure dans le fichier urls.py principal*
393 60 Etienne Pallier
394 60 Etienne Pallier
Class-based views ==> classes controleurs
395 60 Etienne Pallier
Les méthodes get() et post() sont déjà définies, et on peut les surcharger…
396 60 Etienne Pallier
397 60 Etienne Pallier
Avec un template (gabarit), on peut générer autre chose que du html,
398 60 Etienne Pallier
on peut par ex générer du texte, du pdf, un email, un xml…
399 60 Etienne Pallier
400 60 Etienne Pallier
401 60 Etienne Pallier
402 60 Etienne Pallier
Vue liste (et détail) :
403 60 Etienne Pallier
https://docs.djangoproject.com/fr/1.8/topics/class-based-views/generic-display/
404 60 Etienne Pallier
1) todo/views.py
405 60 Etienne Pallier
from django.views.generic import ListView
406 60 Etienne Pallier
from books.models import Publisher
407 60 Etienne Pallier
408 60 Etienne Pallier
class PublisherList(ListView):
409 60 Etienne Pallier
    model = Publisher
410 60 Etienne Pallier
411 60 Etienne Pallier
412 60 Etienne Pallier
2) todolist/urls.py
413 60 Etienne Pallier
from django.conf.urls import url
414 60 Etienne Pallier
from books.views import PublisherList
415 60 Etienne Pallier
416 60 Etienne Pallier
urlpatterns = [
417 60 Etienne Pallier
    url(r'^publishers/$', PublisherList.as_view()),
418 60 Etienne Pallier
]
419 60 Etienne Pallier
420 60 Etienne Pallier
3) todo/templates/todo/
421 60 Etienne Pallier
422 60 Etienne Pallier
423 60 Etienne Pallier
424 60 Etienne Pallier
- Vue Liste : par défaut le template reçoit un objet « objects_list »
425 60 Etienne Pallier
- Vue détail : object (on peut faire object.pk, …)
426 53 Etienne Pallier
427 53 Etienne Pallier
428 53 Etienne Pallier
429 53 Etienne Pallier
---
430 53 Etienne Pallier
431 40 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)%
432 6 Etienne Pallier
433 6 Etienne Pallier
434 1 Etienne Pallier
[[pyros_install_from_start|Pyros installation from the beginning]]