Project Development

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