Project Development

Version 56 (Etienne Pallier, 03/29/2016 11:10 am)

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 36 Etienne Pallier
  * Impossible d'ajouter un pays dans Country depuis admin (erreur sur pyrosuser.name)
16 36 Etienne Pallier
  * Impossible d'ajouter un telescope (erreur sur device.name)
17 37 Etienne Pallier
  * champs booleans: représenter en case à cocher (cf requests.is_alert) : is_alert = models.BooleanField()
18 36 Etienne Pallier
  * Fix plurals:
19 32 Etienne Pallier
20 36 Etienne Pallier
   * Country : plural "countries" and not "countrys"
21 36 Etienne Pallier
   * NrtAnalysiss
22 36 Etienne Pallier
   * Historys
23 1 Etienne Pallier
   * ...
24 37 Etienne Pallier
25 37 Etienne Pallier
 * Models: bien définir les valeurs par défaut
26 37 Etienne Pallier
27 37 Etienne Pallier
  * ex: request.is_alert = False par défaut
28 28 Etienne Pallier
29 28 Etienne Pallier
 * Preload some data for some tables:
30 30 Etienne Pallier
  
31 30 Etienne Pallier
  * country => France, Mexico, ...
32 30 Etienne Pallier
  * sequencetype => 0=routine, 1=alert, ...
33 28 Etienne Pallier
  * userlevel => 0=normal, 1=expert, 2=admin, ...
34 28 Etienne Pallier
  * ...
35 27 Etienne Pallier
36 27 Etienne Pallier
 * updated et created : champs automatiques Django
37 54 Etienne Pallier
<pre>
38 54 Etienne Pallier
class Tache(models.Model):
39 54 Etienne Pallier
	date_limite = models.DateField(auto_now_add)
40 54 Etienne Pallier
</pre>
41 54 Etienne Pallier
42 54 Etienne Pallier
(ajoute automatiquement la date du jour)
43 29 Etienne Pallier
44 29 Etienne Pallier
 * readonly admin interface : https://gist.github.com/aaugustin/1388243
45 35 Etienne Pallier
46 35 Etienne Pallier
 * Ecrire quelques premiers petits tests
47 18 Etienne Pallier
48 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)
49 3 Etienne Pallier
50 3 Etienne Pallier
 * Séparation des BD Django et Pyros
51 3 Etienne Pallier
52 3 Etienne Pallier
 * Intégration des modules Django déjà développés
53 3 Etienne Pallier
54 3 Etienne Pallier
 * Intégration continue avec Jenkins (+ run des tests sur une VM Windows)
55 3 Etienne Pallier
56 3 Etienne Pallier
 * Planifier la suite...
57 3 Etienne Pallier
58 3 Etienne Pallier
 * Doc pour le meeting de mai
59 24 Etienne Pallier
60 55 Etienne Pallier
 * passer la TODO list sur redmine (=> roadmap)
61 55 Etienne Pallier
62 56 Etienne Pallier
 * passer sur sourcesup
63 56 Etienne Pallier
64 24 Etienne Pallier
 * pyrossu : pyrossu!
65 3 Etienne Pallier
66 4 Etienne Pallier
---
67 4 Etienne Pallier
68 4 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}LIENS UTILES%
69 4 Etienne Pallier
70 4 Etienne Pallier
 * Liens vers web local :
71 4 Etienne Pallier
72 4 Etienne Pallier
  * homepage: http://localhost:8000
73 4 Etienne Pallier
  * admin: http://localhost:8000/admin
74 25 Etienne Pallier
75 25 Etienne Pallier
 * Eclipse:
76 26 Etienne Pallier
 
77 26 Etienne Pallier
  * Shift-Ctrl-f (ou Shift-Cmd-f) : reformatage du fichier selon PEP8
78 25 Etienne Pallier
  * Shift-Ctrl-1 : make doc string ...
79 4 Etienne Pallier
80 4 Etienne Pallier
 * Django:
81 4 Etienne Pallier
82 38 Etienne Pallier
  * Coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style
83 38 Etienne Pallier
  * Doc : https://docs.djangoproject.com/en/1.9
84 44 Etienne Pallier
  * (FR) http://docs.djangoproject.com/fr
85 44 Etienne Pallier
  * http://stackoverflow.com/questions/tagged/django
86 44 Etienne Pallier
  * www.django-fr.org/planete
87 44 Etienne Pallier
  * https://www.djangopackages.com/
88 44 Etienne Pallier
  * http://forum.django-fr.org
89 44 Etienne Pallier
  * La mailing list : django@lists.afpy.org
90 44 Etienne Pallier
91 44 Etienne Pallier
92 4 Etienne Pallier
93 4 Etienne Pallier
 * Git docs: 
94 19 Etienne Pallier
95 4 Etienne Pallier
  * Permissions gitlab: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md
96 4 Etienne Pallier
  * https://git-scm.com/docs
97 4 Etienne Pallier
  * https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants
98 4 Etienne Pallier
  * les workflows: https://aresu.dsi.cnrs.fr/spip.php?article219
99 15 Etienne Pallier
  * Git for Eclipse users : http://wiki.eclipse.org/EGit/Git_For_Eclipse_Users
100 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
101 4 Etienne Pallier
102 4 Etienne Pallier
 * CADOR web interface: http://cador.obs-hp.fr/ros/manual/cador_actions.html
103 4 Etienne Pallier
104 4 Etienne Pallier
 * pylint (analyse de code) : https://www.pylint.org
105 4 Etienne Pallier
106 4 Etienne Pallier
 * pyreverse (uml diagrams generation, inclus dans pylint) : https://www.logilab.org/blogentry/6883
107 4 Etienne Pallier
108 4 Etienne Pallier
 * tox (a generic virtualenv management and test command line tool) : https://testrun.org/tox/latest/index.html
109 4 Etienne Pallier
110 5 Etienne Pallier
---
111 5 Etienne Pallier
112 5 Etienne Pallier
113 5 Etienne Pallier
---
114 5 Etienne Pallier
115 5 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}I - DATABASE SCHEMA (v0.2.1)%
116 5 Etienne Pallier
117 5 Etienne Pallier
118 6 Etienne Pallier
{{thumbnail(PYROS_PDM_v021.png, size=300, title=Pyros data model)}}
119 7 Etienne Pallier
120 6 Etienne Pallier
---
121 7 Etienne Pallier
122 6 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}II - Get the project (from gitlab)%
123 20 Etienne Pallier
124 20 Etienne Pallier
h3. Gitlab management interface
125 20 Etienne Pallier
126 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros
127 20 Etienne Pallier
128 20 Etienne Pallier
https://gitlab.irap.omp.eu/epallier/pyros/team
129 20 Etienne Pallier
130 6 Etienne Pallier
h3. Get the project
131 8 Etienne Pallier
132 8 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#II-Get-the-project-from-gitlab
133 7 Etienne Pallier
134 7 Etienne Pallier
---
135 11 Etienne Pallier
136 11 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}III - INSTALLATION%
137 11 Etienne Pallier
138 11 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Project_Installation#III-INSTALLATION
139 11 Etienne Pallier
140 11 Etienne Pallier
---
141 6 Etienne Pallier
142 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)%
143 6 Etienne Pallier
144 6 Etienne Pallier
[[django_backoffice_config|Configuration of the Django Back office (admin)]]
145 9 Etienne Pallier
146 9 Etienne Pallier
---
147 13 Etienne Pallier
148 43 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}V - EVOLUTION OF THE PROJECT%
149 1 Etienne Pallier
150 43 Etienne Pallier
151 43 Etienne Pallier
152 43 Etienne Pallier
h3. Linking the User model to the django's one
153 43 Etienne Pallier
154 43 Etienne Pallier
* Modifications in models.py :
155 43 Etienne Pallier
156 43 Etienne Pallier
    * Rename User model to PyrosUser
157 43 Etienne Pallier
    * Rename user table name to pyros_user
158 43 Etienne Pallier
    * Change all occurences (User -> PyrosUser, users -> pyros_users, ...)
159 43 Etienne Pallier
    * from django.contrib.auth.models import User <== add at the beginning of the file
160 43 Etienne Pallier
    * user = models.OneToOneField(User, on_delete=models.CASCADE) <== add this field in PyrosUser declaration
161 43 Etienne Pallier
    * delete fields in PyrosUser : name, firstname, email, login, pass
162 43 Etienne Pallier
163 43 Etienne Pallier
* Modifications in admin.py :
164 43 Etienne Pallier
165 43 Etienne Pallier
    * Change all occurences (User* -> PyrosUser*, users -> pyros_users, ...)
166 43 Etienne Pallier
167 43 Etienne Pallier
<pre>
168 43 Etienne Pallier
$ python manage.py makemigrations pyrosapp
169 43 Etienne Pallier
$ python manage.py migrate
170 43 Etienne Pallier
</pre>
171 43 Etienne Pallier
172 43 Etienne Pallier
---
173 43 Etienne Pallier
174 43 Etienne Pallier
h3. Manage static files (for admin but also for each application)
175 41 Etienne Pallier
176 41 Etienne Pallier
./manage.py runserver
177 41 Etienne Pallier
178 41 Etienne Pallier
if DEBUG=False, we have errors, missing static files :
179 41 Etienne Pallier
180 41 Etienne Pallier
<pre>
181 41 Etienne Pallier
Not Found: /static/admin/css/base.css
182 41 Etienne Pallier
Not Found: /static/admin/css/login.css
183 41 Etienne Pallier
Not Found: /admin/login
184 41 Etienne Pallier
Not Found: /static/admin/css/base.css
185 41 Etienne Pallier
Not Found: /static/admin/css/login.css
186 41 Etienne Pallier
Not Found: /static/admin/css/base.css
187 41 Etienne Pallier
Not Found: /static/admin/css/login.css
188 41 Etienne Pallier
Not Found: /static/admin/css/base.css
189 41 Etienne Pallier
Not Found: /static/admin/css/dashboard.css
190 41 Etienne Pallier
Not Found: /static/admin/css/base.css
191 41 Etienne Pallier
Not Found: /static/admin/css/base.css
192 41 Etienne Pallier
193 41 Etienne Pallier
</pre>
194 41 Etienne Pallier
195 41 Etienne Pallier
196 41 Etienne Pallier
=> We have to activate the static files management
197 41 Etienne Pallier
198 41 Etienne Pallier
(see https://docs.djangoproject.com/en/1.9/howto/static-files)
199 41 Etienne Pallier
200 41 Etienne Pallier
In pyros/urls.py, add this:
201 41 Etienne Pallier
<pre>
202 41 Etienne Pallier
203 41 Etienne Pallier
from django.conf import settings
204 41 Etienne Pallier
from django.conf.urls.static import static
205 41 Etienne Pallier
206 41 Etienne Pallier
urlpatterns = [
207 41 Etienne Pallier
    url(r'^admin/', admin.site.urls),
208 41 Etienne Pallier
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
209 41 Etienne Pallier
</pre>
210 41 Etienne Pallier
211 41 Etienne Pallier
STATIC_ROOT must be defined in settings and says where is the root of all static files
212 41 Etienne Pallier
213 41 Etienne Pallier
Edit settings.py, add:
214 41 Etienne Pallier
<pre>
215 41 Etienne Pallier
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'public', 'static')
216 41 Etienne Pallier
</pre>
217 41 Etienne Pallier
218 41 Etienne Pallier
219 41 Etienne Pallier
./manage.py collectstatic
220 41 Etienne Pallier
221 41 Etienne Pallier
=> 56 static files copied to '.../PYROS/public/static'
222 41 Etienne Pallier
223 41 Etienne Pallier
(in fact it is in public/static/admin/)
224 41 Etienne Pallier
225 41 Etienne Pallier
Cette commande copie tous les fichiers statiques de toutes les applis
226 41 Etienne Pallier
dans public/static
227 41 Etienne Pallier
228 41 Etienne Pallier
Apache viendra lire ce dossier unique
229 41 Etienne Pallier
230 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 »)
231 41 Etienne Pallier
232 41 Etienne Pallier
233 39 Etienne Pallier
---
234 39 Etienne Pallier
235 45 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}DJANGO SHELL (top cool)%
236 45 Etienne Pallier
237 51 Etienne Pallier
cf page 60 for the ORM methods
238 51 Etienne Pallier
239 45 Etienne Pallier
<pre>
240 45 Etienne Pallier
./manage.py shell
241 45 Etienne Pallier
Python 3.5.1 (default, Mar  2 2016, 03:38:02) 
242 45 Etienne Pallier
(InteractiveConsole)
243 46 Etienne Pallier
244 45 Etienne Pallier
>>> import django
245 46 Etienne Pallier
246 45 Etienne Pallier
>>> from pyrosapp.models import *
247 46 Etienne Pallier
248 45 Etienne Pallier
>>> country = Country(name='mexico', quota=1)
249 45 Etienne Pallier
>>> country.save()
250 50 Etienne Pallier
(ajout si pas d’id, modif si id)
251 50 Etienne Pallier
252 45 Etienne Pallier
>>> country = Country(name='france')
253 45 Etienne Pallier
>>> country.save()
254 45 Etienne Pallier
>>> country.pk
255 45 Etienne Pallier
>>> 2
256 45 Etienne Pallier
257 45 Etienne Pallier
>>> countries = Country.objects.all()
258 45 Etienne Pallier
>>> countries.count
259 45 Etienne Pallier
>>> <bound method QuerySet.count of <Country: mexico>, <Country: france>>
260 45 Etienne Pallier
>>> countries.count()
261 45 Etienne Pallier
>>> 2
262 45 Etienne Pallier
>>> print(countries)
263 45 Etienne Pallier
>>> <Country: mexico>, <Country: france>
264 45 Etienne Pallier
>>> print(countries.query)
265 45 Etienne Pallier
>>> SELECT country.id, country.name, country.desc, country.quota FROM country
266 45 Etienne Pallier
267 45 Etienne Pallier
>>> cs = countries.filter(name__icontains='fran')
268 45 Etienne Pallier
>>> print(cs)
269 45 Etienne Pallier
>>> <Country: france>
270 45 Etienne Pallier
271 45 Etienne Pallier
>>> cs = countries.filter(name__startswith='me')
272 45 Etienne Pallier
>>> print(cs)
273 45 Etienne Pallier
>>> <Country: mexico>
274 45 Etienne Pallier
275 45 Etienne Pallier
</pre>
276 45 Etienne Pallier
277 45 Etienne Pallier
278 45 Etienne Pallier
---
279 45 Etienne Pallier
280 47 Etienne Pallier
h2. %{margin-left:0px; font-weight:bold; font-size:25px;  display:block; color:red;}HOWTO (divers)%
281 47 Etienne Pallier
282 47 Etienne Pallier
283 48 Etienne Pallier
h3. Many to Many
284 48 Etienne Pallier
285 48 Etienne Pallier
tache <=> user
286 48 Etienne Pallier
287 48 Etienne Pallier
tache.user
288 48 Etienne Pallier
user.tache_set
289 48 Etienne Pallier
290 48 Etienne Pallier
291 47 Etienne Pallier
292 47 Etienne Pallier
h3. Pour relier une appli python pure à un projet django :
293 47 Etienne Pallier
294 47 Etienne Pallier
=> Ajouter le src/ dans le pythonpath
295 47 Etienne Pallier
296 47 Etienne Pallier
297 47 Etienne Pallier
h3. Séparer le code métier :
298 47 Etienne Pallier
299 47 Etienne Pallier
=> installer le code métier comme un module via pip
300 47 Etienne Pallier
Couches :
301 47 Etienne Pallier
* présentation
302 47 Etienne Pallier
* métier
303 47 Etienne Pallier
* modèle
304 47 Etienne Pallier
305 49 Etienne Pallier
h3. ORM
306 49 Etienne Pallier
307 49 Etienne Pallier
(cf page 60)
308 49 Etienne Pallier
309 49 Etienne Pallier
b = Book(…)
310 49 Etienne Pallier
b.save() :
311 49 Etienne Pallier
ajout si pas d’id, modif si id
312 49 Etienne Pallier
313 49 Etienne Pallier
Book.objects.all()
314 49 Etienne Pallier
315 49 Etienne Pallier
Book.objects.filter(
316 49 Etienne Pallier
        release__gte=date(2013, 01, 01)
317 49 Etienne Pallier
      ).exclude(
318 49 Etienne Pallier
        borrowed=True
319 49 Etienne Pallier
      )
320 49 Etienne Pallier
321 49 Etienne Pallier
A! La requete est exécutée le plus tard possible, seulement quand django a vraiment besoin de l’exécuter
322 49 Etienne Pallier
323 49 Etienne Pallier
books = Book.objects.exclude(borrowed=True).order_by('title')
324 49 Etienne Pallier
print (books.author)
325 49 Etienne Pallier
326 49 Etienne Pallier
Book.objects.get(pk=12)
327 49 Etienne Pallier
328 49 Etienne Pallier
author = Author.objects.get(pk=25)
329 49 Etienne Pallier
author.books.filter(borrowed=False)
330 49 Etienne Pallier
331 49 Etienne Pallier
(books est le related name déclaré dans la relation manytomany)
332 49 Etienne Pallier
333 47 Etienne Pallier
334 47 Etienne Pallier
---
335 47 Etienne Pallier
336 53 Etienne Pallier
h3. Serveur Web
337 53 Etienne Pallier
338 53 Etienne Pallier
Apache : gère tous les fichiers statiques (images, html…), et délègue les fichiers python au serveur django
339 53 Etienne Pallier
340 53 Etienne Pallier
Moteur web django sera soit du wsgi soit du unicorn
341 53 Etienne Pallier
Par défaut, 1 seul worker, mais on peut en configurer plusieurs,
342 53 Etienne Pallier
l’idéal étant de faire nb coeurs + 1 (le worker maître qui fait le dispatching aux autres)
343 53 Etienne Pallier
344 53 Etienne Pallier
Frontend : Apache ou Ngininx
345 53 Etienne Pallier
Backend : gunicorn (gère facilement des workers) ou uwsgi
346 53 Etienne Pallier
347 53 Etienne Pallier
==> gunicorn library.wsgi
348 53 Etienne Pallier
(à la place de manage runserver ==> A EVITER EN PROD)
349 53 Etienne Pallier
350 53 Etienne Pallier
pip install gunicorn
351 53 Etienne Pallier
352 53 Etienne Pallier
gunicorn library.wsgi
353 53 Etienne Pallier
ou
354 53 Etienne Pallier
gunicorn - - workers 5 library.wsgi
355 53 Etienne Pallier
356 53 Etienne Pallier
(gunicorn == tomcat, serveur d’appli Python)
357 53 Etienne Pallier
358 53 Etienne Pallier
1) URL arrive à Apache, qui dispatche (il gère seul les fichiers statiques, et les fichiers python il les transmet à Django)
359 53 Etienne Pallier
2) le fichier library/urls.py prend le relai pour tout ce qui est django
360 53 Etienne Pallier
361 53 Etienne Pallier
362 53 Etienne Pallier
363 53 Etienne Pallier
On peut ajouter un fichier urls.py pour gérer les urls de l’appli
364 53 Etienne Pallier
(on garde le urls.py général du projet pour gérer les grandes urls)
365 53 Etienne Pallier
366 53 Etienne Pallier
367 53 Etienne Pallier
368 53 Etienne Pallier
369 53 Etienne Pallier
---
370 53 Etienne Pallier
371 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)%
372 6 Etienne Pallier
373 6 Etienne Pallier
374 1 Etienne Pallier
[[pyros_install_from_start|Pyros installation from the beginning]]