Pyros install from start

Version 4 (Etienne Pallier, 03/23/2016 08:32 am)

1 1 Etienne Pallier
h1. PYROS INSTALLATION FROM THE BEGINNING (for dev only, history of the initial project creation)
2 1 Etienne Pallier
3 1 Etienne Pallier
4 1 Etienne Pallier
h3. Install MySql (only if necessary)
5 1 Etienne Pallier
6 4 Etienne Pallier
See in III-Installation
7 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
8 1 Etienne Pallier
9 1 Etienne Pallier
10 1 Etienne Pallier
---
11 1 Etienne Pallier
12 1 Etienne Pallier
h3. Create the database (from sql script generated with Mysql Workbench)
13 1 Etienne Pallier
14 3 Paul Carensac
 * All platforms:
15 1 Etienne Pallier
<pre>
16 1 Etienne Pallier
One liner:
17 1 Etienne Pallier
$ mysql -u root < pyros_create.sql
18 1 Etienne Pallier
19 1 Etienne Pallier
Or :
20 1 Etienne Pallier
$ mysql -u root
21 1 Etienne Pallier
mysql> create database pyros;
22 1 Etienne Pallier
mysql> use pyros;
23 1 Etienne Pallier
mysql> source pyros_create.sql;
24 1 Etienne Pallier
25 1 Etienne Pallier
(
26 1 Etienne Pallier
TODO:
27 1 Etienne Pallier
mysql> grant all on pyros.* to pyros@localhost identified by ‘pyros’;)
28 1 Etienne Pallier
mysql> flush privileges;
29 1 Etienne Pallier
)
30 1 Etienne Pallier
</pre>
31 1 Etienne Pallier
32 1 Etienne Pallier
33 1 Etienne Pallier
h3. Install Python3.5 (only if necessary)
34 1 Etienne Pallier
35 4 Etienne Pallier
See in III-Installation
36 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
37 1 Etienne Pallier
38 1 Etienne Pallier
39 1 Etienne Pallier
h3. Create the project structure
40 1 Etienne Pallier
41 1 Etienne Pallier
<pre>
42 1 Etienne Pallier
$ mkdir PYROS
43 1 Etienne Pallier
</pre>
44 1 Etienne Pallier
45 1 Etienne Pallier
Example of a good organization :
46 1 Etienne Pallier
47 1 Etienne Pallier
1 project = N applis
48 1 Etienne Pallier
1 appli = N models
49 1 Etienne Pallier
A! L’appli est à côté du projet, PAS DEDANS,
50 1 Etienne Pallier
cela facilite la REUTILISATION
51 1 Etienne Pallier
(an appli can be part of many projects => reuse)
52 1 Etienne Pallier
1 appli = 1 Python module, organized for Django, by default = appli web (but not mandatory)
53 1 Etienne Pallier
54 1 Etienne Pallier
<pre>
55 1 Etienne Pallier
56 1 Etienne Pallier
MYPROJECT/
57 1 Etienne Pallier
	REQUIREMENTS.txt
58 1 Etienne Pallier
	src/
59 1 Etienne Pallier
		myproject/
60 1 Etienne Pallier
		appli1/
61 1 Etienne Pallier
		appli2/
62 1 Etienne Pallier
63 1 Etienne Pallier
		appliN/
64 1 Etienne Pallier
65 1 Etienne Pallier
	public/
66 1 Etienne Pallier
		static/
67 1 Etienne Pallier
68 1 Etienne Pallier
	private/
69 1 Etienne Pallier
		venv_py35_pyros/
70 1 Etienne Pallier
71 1 Etienne Pallier
</pre>
72 1 Etienne Pallier
73 1 Etienne Pallier
74 1 Etienne Pallier
Set needed folders:
75 1 Etienne Pallier
<pre>
76 1 Etienne Pallier
$ cd PYROS/
77 1 Etienne Pallier
$ mkdir private public
78 1 Etienne Pallier
$ mkdir public/static
79 1 Etienne Pallier
</pre>
80 1 Etienne Pallier
81 1 Etienne Pallier
82 1 Etienne Pallier
83 1 Etienne Pallier
---
84 1 Etienne Pallier
85 1 Etienne Pallier
h3. Create a Python3 virtual environment dedicated to the project (inside the project folder)
86 1 Etienne Pallier
87 4 Etienne Pallier
See in III-Installation
88 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
89 1 Etienne Pallier
90 1 Etienne Pallier
h3. Activate the Python virtual environment (from inside the project)
91 1 Etienne Pallier
92 4 Etienne Pallier
See in III-Installation
93 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
94 1 Etienne Pallier
95 1 Etienne Pallier
h3. Install the needed Python packages (from within the virtual environment)
96 1 Etienne Pallier
97 4 Etienne Pallier
See in III-Installation
98 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#Install-the-needed-Python-packages-from-within-the-virtual-environment
99 1 Etienne Pallier
(cf manual installation)
100 1 Etienne Pallier
101 1 Etienne Pallier
h3. Create a Django project named PYROS
102 1 Etienne Pallier
103 1 Etienne Pallier
<pre>
104 1 Etienne Pallier
105 1 Etienne Pallier
From inside the project:
106 1 Etienne Pallier
$ pwd
107 1 Etienne Pallier
.../PYROS/
108 1 Etienne Pallier
109 1 Etienne Pallier
$ django-admin startproject pyros
110 1 Etienne Pallier
111 1 Etienne Pallier
Rename the project folder "pyros/" as "src/"
112 1 Etienne Pallier
113 1 Etienne Pallier
$ mv pyros src
114 1 Etienne Pallier
115 1 Etienne Pallier
We have then this architecture:
116 1 Etienne Pallier
117 1 Etienne Pallier
PYROS
118 1 Etienne Pallier
├── REQUIREMENTS.txt
119 1 Etienne Pallier
├── private
120 1 Etienne Pallier
│   └── venv_py35_pyros
121 1 Etienne Pallier
├── public
122 1 Etienne Pallier
│   └── static
123 1 Etienne Pallier
├── src
124 1 Etienne Pallier
│   ├── manage.py
125 1 Etienne Pallier
│   ├── pyros
126 1 Etienne Pallier
│   │   ├── __init__.py
127 1 Etienne Pallier
│   │   ├── settings.py
128 1 Etienne Pallier
│   │   ├── urls.py
129 1 Etienne Pallier
│   │   └── wsgi.py
130 1 Etienne Pallier
131 1 Etienne Pallier
</pre>
132 1 Etienne Pallier
133 1 Etienne Pallier
134 1 Etienne Pallier
135 1 Etienne Pallier
136 1 Etienne Pallier
---
137 1 Etienne Pallier
138 1 Etienne Pallier
h3. Test the project
139 1 Etienne Pallier
140 4 Etienne Pallier
See in III-Installation
141 1 Etienne Pallier
https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#III-INSTALLATION
142 1 Etienne Pallier
143 1 Etienne Pallier
h3. The Web server
144 1 Etienne Pallier
145 1 Etienne Pallier
146 1 Etienne Pallier
Apache : gère tous les fichiers statiques (images, html…), et délègue les fichiers python au serveur django (par défaut)
147 1 Etienne Pallier
148 1 Etienne Pallier
Le fichier pyros/urls.py prend le relai pour tout ce qui est django
149 1 Etienne Pallier
150 1 Etienne Pallier
Le moteur web django sera soit du wsgi soit du unicorn
151 1 Etienne Pallier
152 1 Etienne Pallier
Par défaut, 1 seul worker, mais on peut en configurer plusieurs, l’idéal étant de faire "nb coeurs + 1" 
153 1 Etienne Pallier
(le worker maître qui fait le dispatching aux autres)
154 1 Etienne Pallier
155 1 Etienne Pallier
Frontend : Apache ou Ngininx
156 1 Etienne Pallier
157 1 Etienne Pallier
Backend : gunicorn (gère facilement des workers) ou uwsgi
158 1 Etienne Pallier
159 1 Etienne Pallier
<pre>
160 1 Etienne Pallier
$ gunicorn pyros.wsgi
161 1 Etienne Pallier
(à la place de manage runserver => A EVITER EN PROD)
162 1 Etienne Pallier
163 1 Etienne Pallier
Ou encore:
164 1 Etienne Pallier
165 1 Etienne Pallier
$ gunicorn --workers 5 library.wsgi
166 1 Etienne Pallier
</pre>
167 1 Etienne Pallier
168 1 Etienne Pallier
---
169 1 Etienne Pallier
170 1 Etienne Pallier
h3. Set the database engine as MySql
171 1 Etienne Pallier
172 1 Etienne Pallier
Edit src/pyros/settings.py
173 1 Etienne Pallier
174 1 Etienne Pallier
<pre>
175 1 Etienne Pallier
DATABASES = {
176 1 Etienne Pallier
    'default': {
177 1 Etienne Pallier
        'ENGINE': 'django.db.backends.mysql',
178 1 Etienne Pallier
        'NAME': 'pyros',
179 1 Etienne Pallier
        'USER': 'root',
180 1 Etienne Pallier
        'PASSWORD': ''
181 1 Etienne Pallier
    }
182 1 Etienne Pallier
}
183 1 Etienne Pallier
</pre>
184 1 Etienne Pallier
185 1 Etienne Pallier
---
186 1 Etienne Pallier
187 1 Etienne Pallier
h3. Import the database into Django (with inspectdb)
188 1 Etienne Pallier
189 1 Etienne Pallier
From src/ :
190 1 Etienne Pallier
191 1 Etienne Pallier
<pre>
192 1 Etienne Pallier
$ ./manage.py inspectdb > models.py
193 1 Etienne Pallier
</pre>
194 1 Etienne Pallier
195 1 Etienne Pallier
Issue on Mac OS X:
196 1 Etienne Pallier
<pre>
197 1 Etienne Pallier
Traceback (most recent call last):
198 1 Etienne Pallier
  File "/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 25, in <module>
199 1 Etienne Pallier
    import MySQLdb as Database
200 1 Etienne Pallier
  File "/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/MySQLdb/__init__.py", line 19, in <module>
201 1 Etienne Pallier
    import _mysql
202 1 Etienne Pallier
ImportError: dlopen(/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so, 2): Library not loaded: libmysqlclient.18.dylib
203 1 Etienne Pallier
  Referenced from: /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
204 1 Etienne Pallier
  Reason: image not found
205 1 Etienne Pallier
206 1 Etienne Pallier
=> BOUH !!!
207 1 Etienne Pallier
208 1 Etienne Pallier
LA SOLUTION EST ICI : http://stackoverflow.com/questions/6383310/python-mysqldb-library-not-loaded-libmysqlclient-18-dylib
209 1 Etienne Pallier
210 1 Etienne Pallier
Il suffit de faire ceci:
211 1 Etienne Pallier
212 1 Etienne Pallier
$ sudo mkdir -p /usr/local/lib   
213 1 Etienne Pallier
$ sudo ln -s /Applications/XAMPP/xamppfiles/lib/libmysql* /usr/local/lib/
214 1 Etienne Pallier
215 1 Etienne Pallier
Mais on peut aussi faire ceci:
216 1 Etienne Pallier
217 1 Etienne Pallier
Okay, so the offending file is /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
218 1 Etienne Pallier
219 1 Etienne Pallier
Next, figure out where _mysql.so thinks it should find libmysqlclient.18.dylib:
220 1 Etienne Pallier
221 1 Etienne Pallier
$ otool -L /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
222 1 Etienne Pallier
/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so:
223 1 Etienne Pallier
	libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
224 1 Etienne Pallier
...
225 1 Etienne Pallier
226 1 Etienne Pallier
So, it's looking for libmysqlclient.18.dylib with no path information, let's fix that:
227 1 Etienne Pallier
228 1 Etienne Pallier
$ locate libmysqlclient.18.dylib
229 1 Etienne Pallier
/Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib
230 1 Etienne Pallier
/Library/SystemMigration/History/Migration-68137DFB-CB6A-4FBB-81E2-11BDB5D01E48/QuarantineRoot/usr/lib/libmysqlclient.18.dylib
231 1 Etienne Pallier
232 1 Etienne Pallier
$ sudo install_name_tool -change libmysqlclient.18.dylib /Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
233 1 Etienne Pallier
234 1 Etienne Pallier
Now _mysql.so knows the full path to the library and everything works, regardless of environment variables.
235 1 Etienne Pallier
236 1 Etienne Pallier
$ otool -L /Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so
237 1 Etienne Pallier
/Users/epallier/Documents/_W_more/PROJECTS/GFT/SOFT/PYROS/pyros/venv_py35_pyros/lib/python3.5/site-packages/_mysql.cpython-35m-darwin.so:
238 1 Etienne Pallier
	/Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib (compatibility version 18.0.0, current version 18.0.0)
239 1 Etienne Pallier
...
240 1 Etienne Pallier
241 1 Etienne Pallier
$ ./manage.py inspectdb > models.py
242 1 Etienne Pallier
243 1 Etienne Pallier
=> YES !!!
244 1 Etienne Pallier
</pre>
245 1 Etienne Pallier
246 1 Etienne Pallier
247 1 Etienne Pallier
---
248 1 Etienne Pallier
249 1 Etienne Pallier
h3. Create a Django application named "pyrosapp"
250 1 Etienne Pallier
251 1 Etienne Pallier
From src/ :
252 1 Etienne Pallier
253 1 Etienne Pallier
<pre>
254 1 Etienne Pallier
$ ./manage.py startapp pyrosapp
255 1 Etienne Pallier
</pre>
256 1 Etienne Pallier
257 1 Etienne Pallier
We obtain this structure:
258 1 Etienne Pallier
259 1 Etienne Pallier
<pre>
260 1 Etienne Pallier
261 1 Etienne Pallier
PYROS/
262 1 Etienne Pallier
├── REQUIREMENTS.txt
263 1 Etienne Pallier
├── private/
264 1 Etienne Pallier
│   └── venv_py35_pyros/
265 1 Etienne Pallier
├── public/
266 1 Etienne Pallier
│   └── static/
267 1 Etienne Pallier
├── src/
268 1 Etienne Pallier
│   ├── manage.py
269 1 Etienne Pallier
│   ├── pyros/
270 1 Etienne Pallier
│   │   ├── __init__.py
271 1 Etienne Pallier
│   │   ├── __pycache__
272 1 Etienne Pallier
│   │   ├── settings.py
273 1 Etienne Pallier
│   │   ├── urls.py
274 1 Etienne Pallier
│   │   └── wsgi.py
275 1 Etienne Pallier
│   └── pyrosapp/
276 1 Etienne Pallier
│       ├── __init__.py
277 1 Etienne Pallier
│       ├── admin.py
278 1 Etienne Pallier
│       ├── apps.py
279 1 Etienne Pallier
│       ├── migrations
280 1 Etienne Pallier
│       ├── models.py
281 1 Etienne Pallier
│       ├── tests.py
282 1 Etienne Pallier
│       └── views.py
283 1 Etienne Pallier
284 1 Etienne Pallier
285 1 Etienne Pallier
</pre>
286 1 Etienne Pallier
287 1 Etienne Pallier
---
288 1 Etienne Pallier
289 1 Etienne Pallier
h3. Replace the default pyrosapp models.py with the inspectdb generated one
290 1 Etienne Pallier
291 1 Etienne Pallier
From src/ :
292 1 Etienne Pallier
293 1 Etienne Pallier
<pre>
294 1 Etienne Pallier
$ mv models.py pyrosapp/
295 1 Etienne Pallier
</pre>
296 1 Etienne Pallier
297 1 Etienne Pallier
Add pyrosapp to the project's applications :
298 1 Etienne Pallier
299 1 Etienne Pallier
Edit src/pyros/settings.py
300 1 Etienne Pallier
301 1 Etienne Pallier
<pre>
302 1 Etienne Pallier
INSTALLED_APPS = [
303 1 Etienne Pallier
    'django.contrib.admin',
304 1 Etienne Pallier
    'django.contrib.auth',
305 1 Etienne Pallier
    'django.contrib.contenttypes',
306 1 Etienne Pallier
    'django.contrib.sessions',
307 1 Etienne Pallier
    'django.contrib.messages',
308 1 Etienne Pallier
    'django.contrib.staticfiles',
309 1 Etienne Pallier
    'pyrosapp',
310 1 Etienne Pallier
]
311 1 Etienne Pallier
</pre>
312 1 Etienne Pallier
313 1 Etienne Pallier
---
314 1 Etienne Pallier
315 1 Etienne Pallier
h3. Fix and improve the pyrosapp models.py file (generated by inspectdb)
316 1 Etienne Pallier
317 1 Etienne Pallier
h3. Set Requirements
318 1 Etienne Pallier
319 1 Etienne Pallier
<pre>
320 1 Etienne Pallier
$ pip freeze > REQUIREMENTS.txt
321 1 Etienne Pallier
</pre>
322 1 Etienne Pallier
323 1 Etienne Pallier
324 1 Etienne Pallier
---
325 1 Etienne Pallier
326 1 Etienne Pallier
h3. Initialize the git repository
327 1 Etienne Pallier
328 1 Etienne Pallier
*Git global setup:*
329 1 Etienne Pallier
330 1 Etienne Pallier
<pre>
331 1 Etienne Pallier
$ git config --global user.name "Etienne Pallier"
332 1 Etienne Pallier
$ git config --global user.email "etienne.pallier@irap.omp.eu"
333 1 Etienne Pallier
334 1 Etienne Pallier
$ cat ~/.gitconfig 
335 1 Etienne Pallier
[user]
336 1 Etienne Pallier
	name = Etienne Pallier
337 1 Etienne Pallier
	email = epallier@irap.omp.eu
338 1 Etienne Pallier
[http]
339 1 Etienne Pallier
	sslVerify = false
340 1 Etienne Pallier
</pre>
341 1 Etienne Pallier
342 1 Etienne Pallier
343 1 Etienne Pallier
*Create a new repository:*
344 1 Etienne Pallier
345 1 Etienne Pallier
<pre>
346 1 Etienne Pallier
$ cd PYROS/
347 1 Etienne Pallier
348 1 Etienne Pallier
Define files and folders to be ignored:
349 1 Etienne Pallier
$ vi .gitignore
350 1 Etienne Pallier
.DS_Store
351 1 Etienne Pallier
private
352 1 Etienne Pallier
__pycache__
353 1 Etienne Pallier
354 1 Etienne Pallier
$ touch README.md
355 1 Etienne Pallier
356 1 Etienne Pallier
$ git add README.md
357 1 Etienne Pallier
358 1 Etienne Pallier
$ git commit -m "first commit"
359 1 Etienne Pallier
360 1 Etienne Pallier
$ git remote add origin https://gitlab.irap.omp.eu/epallier/pyros.git
361 1 Etienne Pallier
362 1 Etienne Pallier
$ git push -u origin master
363 1 Etienne Pallier
364 1 Etienne Pallier
$ git add .
365 1 Etienne Pallier
366 1 Etienne Pallier
( if you want to be sure to add ALL files: 
367 1 Etienne Pallier
$ git add -A
368 1 Etienne Pallier
)
369 1 Etienne Pallier
370 1 Etienne Pallier
( if you wanted to remove added files, just type:
371 1 Etienne Pallier
$ git reset HEAD
372 1 Etienne Pallier
)
373 1 Etienne Pallier
374 1 Etienne Pallier
$ git commit -m "first full project commit"
375 1 Etienne Pallier
376 1 Etienne Pallier
$ git push -u origin master
377 1 Etienne Pallier
Counting objects: 43, done.
378 1 Etienne Pallier
Delta compression using up to 4 threads.
379 1 Etienne Pallier
Compressing objects: 100% (41/41), done.
380 1 Etienne Pallier
Writing objects: 100% (43/43), 575.13 KiB ö 0 bytes/s, done.
381 1 Etienne Pallier
Total 43 (delta 2), reused 0 (delta 0)
382 1 Etienne Pallier
To https://gitlab.irap.omp.eu/epallier/pyros.git
383 1 Etienne Pallier
   9c7128c..64501c9  master -> master
384 1 Etienne Pallier
Branch master set up to track remote branch master from origin.
385 1 Etienne Pallier
386 1 Etienne Pallier
$ git status
387 1 Etienne Pallier
On branch master
388 1 Etienne Pallier
Your branch is up-to-date with 'origin/master'.
389 1 Etienne Pallier
nothing to commit, working directory clean
390 1 Etienne Pallier
391 1 Etienne Pallier
</pre>
392 1 Etienne Pallier
393 1 Etienne Pallier
394 1 Etienne Pallier
---
395 1 Etienne Pallier
396 1 Etienne Pallier
h3. Fix and improve the pyrosapp models.py file (generated by inspectdb)
397 1 Etienne Pallier
398 1 Etienne Pallier
Once models.py file generated, we need to delete the database and create an empty one :
399 1 Etienne Pallier
 
400 1 Etienne Pallier
<pre>
401 1 Etienne Pallier
$ mysql -u root [-p (if password needed)]
402 1 Etienne Pallier
403 1 Etienne Pallier
mysql> DROP DATABSE pyros
404 1 Etienne Pallier
mysql> CREATE SCHEMA IF NOT EXISTS 'pyros' DEFAULT CHARACTER SET utf8;
405 1 Etienne Pallier
406 1 Etienne Pallier
</pre>
407 1 Etienne Pallier
408 1 Etienne Pallier
Then edit pyrosapp/models.py :
409 1 Etienne Pallier
410 1 Etienne Pallier
 * Change 'managed = False' to 'managed = True' for every model
411 1 Etienne Pallier
412 1 Etienne Pallier
 * Change classes names to CamelCase (do not change the 'db_table = ...' lines). *Be careful* : it is needed to change all occurences :
413 1 Etienne Pallier
414 1 Etienne Pallier
    * NrtAlanysis
415 1 Etienne Pallier
    * ScheduleHistory
416 1 Etienne Pallier
    * ScientificProgram
417 1 Etienne Pallier
    * SequenceType
418 1 Etienne Pallier
    * SiteWatch
419 1 Etienne Pallier
    * SiteWatchHistory
420 1 Etienne Pallier
    * StrategyObs
421 1 Etienne Pallier
    * UserLevel
422 1 Etienne Pallier
    * WeatherWatch
423 1 Etienne Pallier
    * WeatherWatchHistory
424 1 Etienne Pallier
425 1 Etienne Pallier
 * Change the deleting mode from 'models.DO_NOTHING' to 'models.CASCADE' for the following foreign keys :
426 1 Etienne Pallier
427 1 Etienne Pallier
    * Image.plan
428 1 Etienne Pallier
    * Plan.album
429 1 Etienne Pallier
    * Album.sequence
430 1 Etienne Pallier
    * Sequence.request
431 1 Etienne Pallier
432 1 Etienne Pallier
 * Change the 'ForeignKey' liaisons to 'OneToOneField' liaisons (just replace ForeignKey by OneToOneField), and change deleting mode to 'models.CASCADE' for the following foreign keys :
433 1 Etienne Pallier
434 1 Etienne Pallier
    * Alert.request
435 1 Etienne Pallier
    * Detector.device
436 1 Etienne Pallier
    * Filter.device
437 1 Etienne Pallier
    * Telescope.device
438 1 Etienne Pallier
439 1 Etienne Pallier
 * We need to redefine many to many relationships for the following classes :
440 1 Etienne Pallier
441 1 Etienne Pallier
    * User - ScientificProgram :
442 1 Etienne Pallier
443 1 Etienne Pallier
        * add 'users = models.ManyToManyField('User')' in ScientificProgram class
444 1 Etienne Pallier
        * delete UserHasScientificProgram class
445 1 Etienne Pallier
446 1 Etienne Pallier
    * Sequence - ScheduleHistory
447 1 Etienne Pallier
448 1 Etienne Pallier
        * add 'sequences = models.ManyToManyField('Sequence')' in ScheduleHistory class
449 1 Etienne Pallier
        * delete ScheduleHasSequences class
450 1 Etienne Pallier
451 1 Etienne Pallier
452 1 Etienne Pallier
 * For each ForeignKey and ManyToManyField creation in models.py, add the 'related_name=[...]' named parameter, as in the following examples :
453 1 Etienne Pallier
454 1 Etienne Pallier
<pre>
455 1 Etienne Pallier
class Sequence(models.Model):
456 1 Etienne Pallier
    request = models.ForeignKey(Request, models.CASCADE, related_name="sequences")
457 1 Etienne Pallier
    sequencetype = models.ForeignKey('SequenceType', models.DO_NOTHING, related_name="sequences")
458 1 Etienne Pallier
    schedule = models.ForeignKey(Schedule, models.DO_NOTHING, related_name="sequences")
459 1 Etienne Pallier
    name = models.CharField(max_length=45, blank=True, null=True)
460 1 Etienne Pallier
    desc = models.TextField(blank=True, null=True)
461 1 Etienne Pallier
    ...
462 1 Etienne Pallier
463 1 Etienne Pallier
class ScheduleHistory(models.Model):
464 1 Etienne Pallier
    sequences = models.ManyToManyField('Sequence', related_name='schedulehistorys')
465 1 Etienne Pallier
    created = models.DateTimeField(blank=True, null=True)
466 1 Etienne Pallier
    ...
467 1 Etienne Pallier
468 1 Etienne Pallier
</pre>
469 1 Etienne Pallier
470 1 Etienne Pallier
 * Finally apply modifications to the database :
471 1 Etienne Pallier
472 1 Etienne Pallier
<pre>
473 1 Etienne Pallier
$ pwd
474 1 Etienne Pallier
.../PYROS/src
475 1 Etienne Pallier
$ python manage.py makemigrations pyrosapp
476 1 Etienne Pallier
$ python manage.py migrate
477 1 Etienne Pallier
</pre>
478 1 Etienne Pallier
479 1 Etienne Pallier
---
480 1 Etienne Pallier
481 1 Etienne Pallier
h3. CONFIGURATION of the Django Back Office (administration interface)
482 1 Etienne Pallier
483 1 Etienne Pallier
cf https://projects.irap.omp.eu/projects/pyros/wiki/Wiki#IV-CONFIGURATION-of-the-Django-Back-Office-administration-interface