Project Development

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