**Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été révisée.**

# Howto Django

## Installation

Pré-requis : on installe Apache-ITK, par exemple en suivant la superbe documentation [wiki:HowtoLAMP/Apache]

~~~
# apt install python libapache2-mod-wsgi python-virtualenv python-dev build-essential
~~~

On crée un compte (voir [wiki:HowtoLAMP/Apache]) et on configure le Virtualhost associé,
en ajustant les instructions ainsi :

~~~
AssignUserID www-jdoe jdoe
WSGIScriptAlias / /home/jdoe/public/mysite/django.wsgi
#Alias /media/ /usr/share/python-support/python-django/django/contrib/admin/media/
~~~

L'idée est d'installer un certain nombre de modules Python de façon globale, et de permettre
à chaque compte d'en ajouter ou d'en avoir de plus récents avec l'outil _virtualenv_

~~~
# apt install python-django python-mysqldb python-imaging python-html5lib libxml2-dev libxslt1-dev virtualenv python-pip
~~~

On se connecte ensuite avec le compte concerné, puis on peut installer des modules Python supplémentaires ainsi :

~~~
$ virtualenv lib
New python executable in lib/bin/python
Installing setuptools............done.
$ source lib/bin/activate
(lib)$ easy_install pisa relatorio django-extensions
Searching for pisa
Reading <http://pypi.python.org/simple/pisa/>
Reading <http://www.xhtml2pdf.com>
Reading <http://www.htmltopdf.org/>
Reading <http://www.htmltopdf.org/download.html>
Reading <http://pisa.spirito.de/>
Reading <http://pisa.spirito.de/download.html>
Best match: pisa 3.0.33
Downloading <http://pypi.python.org/packages/source/p/pisa/pisa-3.0.33.zip#md5=2a6e9ddba828caf9d97d4d1c0bb889e1>
Processing pisa-3.0.33.zip
Running pisa-3.0.33/setup.py -q bdist_egg --dist-dir /tmp/easy_install-kIDfVZ/pisa-3.0.33/egg-dist-tmp-lUVUuk
zip_safe flag not set; analyzing archive contents...
ho.__init__: module references __path__
ho.__init__: module references __path__
sx.__init__: module references __path__
sx.__init__: module references __path__
Adding pisa 3.0.33 to easy-install.pth file
Installing pisa script to /home/jdoe/lib/bin
Installing xhtml2pdf script to /home/jdoe/lib/bin

Installed /home/jdoe/lib/lib/python2.5/site-packages/pisa-3.0.33-py2.5.egg
Processing dependencies for pisa
Finished processing dependencies for pisa
Searching for relatorio
Reading <http://pypi.python.org/simple/relatorio/>
Reading <http://relatorio.openhex.org/>
Reading <http://relatorio.openhex.org>
Best match: relatorio 0.5.5
Downloading <http://pypi.python.org/packages/source/r/relatorio/relatorio-0.5.5.tar.gz#md5=06e841b7c1fce99461534e5cb8300b8f>
Processing relatorio-0.5.5.tar.gz
Running relatorio-0.5.5/setup.py -q bdist_egg --dist-dir /tmp/easy_install-W_rscM/relatorio-0.5.5/egg-dist-tmp-Hb4E3c
zip_safe flag not set; analyzing archive contents...
relatorio.reporting: module references __file__
Adding relatorio 0.5.5 to easy-install.pth file

Installed /home/jdoe/lib/lib/python2.5/site-packages/relatorio-0.5.5-py2.5.egg
Processing dependencies for relatorio
Searching for Genshi>=0.5
Reading <http://pypi.python.org/simple/Genshi/>
Reading <http://genshi.edgewall.org/>
Reading <http://genshi.edgewall.org/wiki/Download>
Best match: Genshi 0.6
Downloading <http://ftp.edgewall.com/pub/genshi/Genshi-0.6-py2.5.egg>
Processing Genshi-0.6-py2.5.egg
Moving Genshi-0.6-py2.5.egg to /home/jdoe/lib/lib/python2.5/site-packages
Adding Genshi 0.6 to easy-install.pth file

Installed /home/jdoe/lib/lib/python2.5/site-packages/Genshi-0.6-py2.5.egg
Finished processing dependencies for relatorio
Searching for django-extensions
Reading <http://pypi.python.org/simple/django-extensions/>
Reading <http://code.google.com/p/django-command-extensions/>
Reading <http://github.com/django-extensions/django-extensions>
Best match: django-extensions 0.6
Downloading <http://pypi.python.org/packages/source/d/django-extensions/django-extensions-0.6.tar.gz#md5=b90b1a412bb7a1f0a18ef1c05663f1d7>
Processing django-extensions-0.6.tar.gz
Running django-extensions-0.6/setup.py -q bdist_egg --dist-dir /tmp/easy_install-j_GIdw/django-extensions-0.6/egg-dist-tmp-5xofTf
zip_safe flag not set; analyzing archive contents...
django_extensions.management.utils: module references __file__
django_extensions.management.commands.syncdata: module references __file__
django_extensions.management.commands.show_templatetags: module MAY be using inspect.getabsfile
django_extensions.management.commands.create_app: module references __path__
django_extensions.management.commands.runprofileserver: module references __path__
django_extensions.management.commands.create_jobs: module references __file__
django_extensions.management.commands.create_jobs: module references __path__
django_extensions.management.commands.runserver_plus: module references __path__
django_extensions.management.commands.create_command: module references __path__
Adding django-extensions 0.6 to easy-install.pth file

Installed /home/jdoe/lib/lib/python2.5/site-packages/django_extensions-0.6-py2.5.egg
Processing dependencies for django-extensions
Finished processing dependencies for django-extensions
~~~

On notera l'ajout de _(lib)_ au PS1 pour signaler que l'on utilise virtualenv.
Si l'on veut en sortir :

~~~
(lib)$ deactivate
$
~~~

## Focus sur Virtualenv

_virtualenv_ permet de se créer un environnement en tant qu'utilisateur
avec ses propres versions de bibliothèques, etc.

Une bonne idée est d'utiliser les bibliothèques du système, et d'en installer
dans _virtualenv_ que si besoin. C'était le comportement par défaut, mais dans
les versions récentes, cela a changé :-( Dans les versions récentes, il faut
donc utiliser l'option _--system-site-packages_ !!

Fichier de configuration : _~/.virtualenv/virtualenv.ini_

~~~
[virtualenv]
system-site-packages = true
~~~

## Focus sur WSGI / modwsgi

<http://www.wsgi.org/>

<http://code.google.com/p/modwsgi/>

Pour valider le bon fonctionnement de _modwsgi_, on peut créer un script hello.wsgi suivant :

~~~
def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]
~~~

Et l'on ajoute l'instruction suivante dans le VirtualHost :

~~~
WSGIScriptAlias /hello /var/www/hello.wsgi
~~~

Voir <http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide>

Configuration avancée de modwsgi :

<http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives>

## Développement Django

On peut maintenant faire du Django :

~~~
$ cd
$ mkdir public
$ cd public
$ django-admin --version
1.1.1
$ django-admin startproject mysite
$ cd mysite
$ vim django.wsgi
$ vim settings.py
$ vim urls.py
~~~

Voici un exemple de fichier _django.wsgi_ qui n'utilise pas Virtualenv :

~~~
import os
import sys

import site

sys.path.append('/home/jdoe/django/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
~~~

Pour utiliser Virtualenv, on ajoutera la ligne suivante (après _import site_) :

~~~
site.addsitedir('/home/jdoe/lib/lib/python2.6/site-packages')
~~~

Vous devez aussi compléter les paramètres de bases de données dans _settings.py_ :

~~~
DATABASE_ENGINE = 'mysql'
DATABASE_NAME...
~~~

Et initialiser les tables :

~~~
$ cd ~/public/mysite
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'jdoe'): 
E-mail address: jdoe@example.com
Password: 
Password (again): 
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
~~~

À vous de poursuivre... car cela devient du développement !

## Installation des applications admin et admin/doc

On active dans le fichier _urls.py_ :

~~~
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/', include(admin.site.urls)),
)
~~~

Et dans _settings.py_ on ajoute :

~~~
INSTALLED_APPS = (
    [...]
    'django.contrib.admin',
    'django.contrib.admindocs',
)
~~~

Et on met à jour la base de données :

~~~
$ cd ~/public/mysite
$ python manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model
~~~

Et voilà, vous devriez pouvoir accéder
aux apps admin et admin/doc via les URL
<http://jdoe.example.com/admin/> et <http://jdoe.example.com/admin/doc/>



## Mise-à-jour de Django

Le backport de Django sous Debian Lenny est en version 1.1.1 Pour diverses raisons, vous pouvez vouloir avoir une version plus récente de Django.
Dans ce cas, il faut le gérer au niveau du compte avec _virtualenv_ :

~~~
$ cd ~/lib
$ source bin/activate
(lib)$ easy_install Django
Searching for Django
Reading <http://pypi.python.org/simple/Django/>
Reading <http://www.djangoproject.com/>
Best match: Django 1.2.4
Downloading <http://media.djangoproject.com/releases/1.2/Django-1.2.4.tar.gz>
Processing Django-1.2.4.tar.gz
Running Django-1.2.4/setup.py -q bdist_egg --dist-dir /tmp/easy_install-c7zimn/Django-1.2.4/egg-dist-tmp-W72Kh6
zip_safe flag not set; analyzing archive contents...
django.test._doctest: module references __file__
django.test._doctest: module MAY be using inspect.getsourcefile
django.test.simple: module references __file__
django.db.utils: module references __file__
django.db.models.loading: module references __file__
django.core.management.__init__: module references __file__
django.core.management.__init__: module references __path__
django.core.management.base: module references __path__
django.core.management.sql: module references __file__
django.core.management.commands.makemessages: module references __file__
django.core.management.commands.loaddata: module references __file__
django.core.management.commands.loaddata: module references __path__
django.core.servers.base<http:> module references __path__
django.contrib.flatpages.tests.views: module references __file__
django.contrib.flatpages.tests.middleware: module references __file__
django.contrib.flatpages.tests.csrf: module references __file__
django.contrib.admindocs.views: module references __file__
django.contrib.gis.tests.geogapp.tests: module references __file__
django.contrib.gis.tests.layermap.tests: module references __file__
django.contrib.gis.tests.geo3d.tests: module references __file__
django.contrib.gis.geometry.test_data: module references __file__
django.contrib.auth.tests.views: module references __file__
django.views.i18n: module references __file__
django.conf.__init__: module references __file__
django.conf.project_template.manage: module references __file__
django.utils.autoreload: module references __file__
django.utils.module_loading: module references __path__
django.utils.version: module references __path__
django.utils.translation.trans_real: module references __file__
django.template.loaders.app_directories: module references __file__
Adding Django 1.2.4 to easy-install.pth file
Installing django-admin.py script to /home/jdoe/lib/bin

Installed /home/jdoe/lib/lib/python2.5/site-packages/Django-1.2.4-py2.5.egg
Processing dependencies for Django
Finished processing dependencies for Django
~~~

Notez que dans ce cas là, vous devrez gérer vous même les futurs problèmes de sécurité !
Si vous pouvez vous le permettre, vous pourrez mettre ainsi mettre à jour Django via :

~~~
$ cd ~/lib
$ source bin/activate
(lib)$ easy_install -U Django
~~~

## Gunicorn

Gunicorn est un service WSGI qui peut être intégré avec Django. Le service peut être géré avec systemd. On définira deux fichiers :

* `/etc/systemd/system/gunicorn.service`

~~~
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=mon_user
Group=www-data
WorkingDirectory=/chemin/vers/mon_env
ExecStart=/chemin/vers/mon_env/venv/bin/gunicorn \
          --access-logfile /var/log/gunicorn.log \
          --workers 4 \
          --bind unix:/run/gunicorn.sock \
          mon_env.wsgi:application

[Install]
WantedBy=multi-user.target
~~~

* `/etc/systemd/system/gunicorn.socket`

~~~
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target
~~~

* Dans son _vhost_ Nginx :

~~~
server {
[…]
    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
[…]
}
~~~
