Project Development

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