Ghislain Bidaut
(ghislain.bidaut@inserm.fr)
IR Cibi Platform (CRCM Integrative Bioinformatics)
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>My clinical Trials List</title>
6 </head>
7 <body>
8 <h1>Clinical Trial List</h1>
9 <p>Please find here the list of clinical trials</p>
10 <table>
11 <tr><th>ID</th><th>Description</th><th>PI</th><th>e-mail</th></tr>
12 <tr><td>Breast_1</td><td>Breast Cancer Clinical Trial 1</td>
13 <td>Jean-Claude Jesaistout</td><td>jc@free.fr</td></tr>
14 <tr><td>Breast2</td><td>Breast Cancer Clinical Trial 2</td>
15 <td>Albert Einstein</td><td>ae@free.fr</td></tr>
16 </table>
17 </body>
18 </html>
OK this data is accessible by all but, it would be better if:
- user interface
- data
- program that links interface and data
Were separated.
- Also better if display was prettier.
1 pip install Django
2 django-admin startproject myscientificlims .
3 ls -l
4 -rw-r--r-- 1 bidaut staff 36864 8 jui 09:33 db.sqlite3
5 -rwxr-xr-x 1 bidaut staff 259 8 jui 09:29 manage.py
6 drwxr-xr-x 9 bidaut staff 306 13 jui 14:23 myscientificlims/
7 ls -l myscientificlims
8 -rw-r--r-- 1 bidaut staff 0 8 jui 09:29 __init__.py
9 -rw-r--r-- 1 bidaut staff 2668 8 jui 09:29 settings.py
10 -rw-r--r-- 1 bidaut staff 766 8 jui 09:29 urls.py
11 -rw-r--r-- 1 bidaut staff 409 8 jui 09:29 wsgi.py
Manage.py allows for managing the project, starting the server, deploying the database, etc...
In settings.py, change Timezone and Database parameters, then issue the following commands.
1 python manage.py migrate
2 python manage.py runserver
Then, see the development server in action at: http://127.0.0.1:8000/
Great, now let's add some content!
We have created the global project. Functionalities (actions) are added through applications. Each functionality must correspond to a single application and action.
1 python manage.py startapp clinicalmanager
2 ls -l clinicalmanager/
3
4 total 32
5 -rw-r--r-- 1 bidaut staff 0 13 jui 15:19 __init__.py
6 -rw-r--r-- 1 bidaut staff 63 13 jui 15:19 admin.py
7 drwxr-xr-x 3 bidaut staff 102 13 jui 15:19 migrations/
8 -rw-r--r-- 1 bidaut staff 57 13 jui 15:19 models.py
9 -rw-r--r-- 1 bidaut staff 60 13 jui 15:19 tests.py
10 -rw-r--r-- 1 bidaut staff 63 13 jui 15:19 views.py
And add 'clinicalmanager' in 'INSTALLED_APPS'.' (settings.py).
OK, now we have a complete skeleton for our app.
Clinical Trial
PI
1 class ClinicalTrial(models.Model):
2
3 title = models.CharField(max_length=100, unique=True)
4 internal_identifier = models.CharField(max_length=100, unique=True,
5 validators=[validate_alphanumerical])
1 class ClinicalTrial(models.Model):
2
3 title = models.CharField(max_length=100, unique=True)
4 internal_identifier = models.CharField(max_length=100, unique=True,
5 validators=[validate_alphanumerical])
6
7 isConfidential = models.BooleanField(default=True)
8
9 description = models.TextField(max_length=10000)
10 opening_date = models.DateField()
1 class ClinicalTrial(models.Model):
2
3 title = models.CharField(max_length=100, unique=True)
4 internal_identifier = models.CharField(max_length=100, unique=True,
5 validators=[validate_alphanumerical])
6
7 isConfidential = models.BooleanField(default=True)
8
9 description = models.TextField(max_length=10000)
10 opening_date = models.DateField()
11
12 category = models.ManyToManyField(Category)
13 pi = models.ManyToManyField(PI)
1 class ClinicalTrial(models.Model):
2
3 title = models.CharField(max_length=100, unique=True)
4 internal_identifier = models.CharField(max_length=100, unique=True,
5 validators=[validate_alphanumerical])
6
7 isConfidential = models.BooleanField(default=True)
8
9 description = models.TextField(max_length=10000)
10 opening_date = models.DateField()
11
12 category = models.ManyToManyField(Category)
13 pi = models.ManyToManyField(PI)
14
15 class PI(models.Model):
16 salutation = models.CharField(max_length=10)
17 first_name = models.CharField(max_length=400)
18 last_name = models.CharField(max_length=400)
19 email = models.EmailField(blank=True) # Optional
20
21 class Category(models.Model):
22 category = models.CharField(max_length=1000)
1 class PI(models.Model):
2
3 salutation = models.CharField(max_length=10)
4 first_name = models.CharField(max_length=400)
5 last_name = models.CharField(max_length=400)
6 email = models.EmailField(blank=True) # Optional
7
8 # proper string representation
9 def __unicode__(self):
10 return '%s %s' % (self.first_name, self.last_name)
1 python manage.py makemigrations clinicalmanager
2 0001_initial.py:
3 - Create model Category
4 - Create model PI
5 - Create model ClinicalTrial
6 python manage.py migrate clinicalmanager
7 Operations to perform:
8 Apply all migrations: clinicalmanager
9 Running migrations:
10 Rendering model states... DONE
11 Applying clinicalmanager.0001_initial... OK
12 Applying clinicalmanager.0002_auto_20160613_1342... OK
13 Applying clinicalmanager.0003_auto_20160613_1342... OK
14 python manage.py runserver
1 $ python manage.py createsuperuser
2 Username: admin
3 Email address: admin@admin.com
4 Password:
5 Password (again):
6 Superuser created successfully.
1 class ClinicalTrialAdmin(admin.ModelAdmin):
2 list_display = ('title', 'internal_identifier', 'isConfidential', 'opening_date', 'status', 'description')
3 list_filter = ('title', 'internal_identifier', 'isConfidential', 'opening_date', 'status')
4
5 class PIAdmin(admin.ModelAdmin):
6 list_display = ('last_name', 'first_name', 'salutation', 'email')
7 list_filter = ('first_name', 'last_name')
8
9 class CategoryAdmin(admin.ModelAdmin):
10 list_display = ('category', )
11 list_filter = ( 'category', )
12
13 # Register your models here.
14 admin.site.register(ClinicalTrial, ClinicalTrialAdmin)
15 admin.site.register(PI, PIAdmin)
16 admin.site.register(Category, CategoryAdmin)
What's an URL ? Uniform Resource Locator (e.g http://www.debian.org).
Django manages URLs in a smart fashion in order to retrieve information using the url.py file.
Examples:
List all clinical trials:
Display clinical trial 'Breast_1':
1 from django.conf.urls import include, url
2 from django.contrib import admin
3
4 urlpatterns = [
5 # Examples:
6 # url(r'^$', 'mysite.views.home', name='home'),
7 # url(r'^blog/', include('blog.urls')),
8
9 url(r'^admin/', include(admin.site.urls)),
10 ]
Examples:
http://128.0.0.1:8000/trial/Breast_1
1 url(r'^list/$', clinicaltrials_list, name='list'),
2 url(r'^trial/(\w+)/$', clinicaltrial_view, name='clinicaltrial'),
Let's do the http://128.0.0.1:8000/trial/Breast_1 case.
The code in views.py connects data from the database to the viewable content.
1 def clinicaltrial_view(request, clinicaltrial_id):
2
3 # Get clinical trial with clinical ID
4 clinicaltrial = ClinicalTrial.objects.get(
5 internal_identifier=clinicaltrial_id)
6
7 return render_to_response("clinicaltrials/trial.html", {
8 'clinicaltrial': clinicaltrial,
9 }, RequestContext(request))
File clinicalmanager/template/base.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <title>{% block title %}{% endblock %}</title>
6 </head>
7
8 <body>
9 <h1 class="title">Clinical Trial Management System</h1>
10 <div class="container">
11 {% block content %}{% endblock %}
12 </div>
13 {% block footer %}
14 <footer>
15 <p class="footer">(c) Clinicaltrial System - Copyright Ghislain Bidaut 2016 - Droits réservés.</p>
16 </footer>
17 {% endblock %}
18 </body>
19 </html>
File clinicalmanager/templates/trial.html
1 {% extends "base.html" %}
2 {% block title %}Essai [{{ clinicaltrial.title }}]{% endblock %}
3
4 {% block content %}
5
6 <h2>Essai clinique {{ clinicaltrial.title }} [{{ clinicaltrial.internal_identifier }}]</h2>
7
8 {% if clinicaltrial.isConfidential %}
9 <p class="error">Essai Confidentiel</p>
10 {% else %}
11 <p class="success">Essai Non Confidentiel</p>
12 {% endif %}
13
14 <h3>Date d'ouverture</h3>
15 <p>{{ clinicaltrial.opening_date }}</p>
16 ...
File clinicalmanager/templates/trial.html
1 ...
2 <h3>Pathologies(s)</h3>
3 <p>
4 <ul>
5 {% for cate in clinicaltrial.category.all %}
6 <li>{{ cate }}</li>
7 {% endfor %}
8
9 </ul>
10 </p>
11
12 <h3>Description</h3>
13 <p>{{ clinicaltrial.description }}</p>
14
15
16 {% endblock %}
To make things prettier.
Example: Skeleton.
Add following in settings.py
1 STATIC_URL = '/static/'
2
3 STATICFILES_DIRS = (
4 os.path.join(BASE_DIR, "static"),
5 '/var/www/static/',
6 )
Data is then served with instruction as follows
1 <link rel="stylesheet" href="{% static "Skeleton-2.0.4/css/normalize.css"
2 %}"/>
Presentation created with Python Landslide
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |