Project Development

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