Project Development

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