Project Development

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