Project Development

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