URL: https://linuxfr.org/users/flan--2/journaux/djangofloor Title: DjangoFloor Authors: flan Date: 2015年04月25日T22:19:28+02:00 License: CC By-SA Tags: django, redis et python Score: 5 Même si je ne suis pas développeur web, j'ai eu à faire (plus ou moins volontairement) un certain nombre de sites. Il y a quelques années, j'ai eu la chance de partir sur le couple Python + Django pour faire un premier site web (http://www.aviationsmilitaires.net/ pour les curieux), et c'est un choix que je n'ai jamais regretté par la suite. En revanche, j'ai pu constater quelques manques, principalement deux : * la gestion des paramètres et de l'installation * les websockets Accessoirement, il y avait toute une palanquée de petits réglages à faire systématiquement et de paquets à ajouter. Projets inclus ============== Je considère que l'espace disque ne coûte pas grand-chose, donc c'est sans remord que j'ai mis ces paquets en dépendance. Je pars également du principe qu'on va utiliser du Redis pour pas mal d'usages. * uwsgi * bootstrap3 (django-bootstrap3 et django-admin-bootstrapped) * font-awesome * CSS et JS (django-pipeline, jsmin et rcssmin) * authentificaiton (django-allauth) * gestion de tâches (celery via Redis) * cache, websockets et sessions (django-websocket-redis, django-redis-sessions-fork, django-redis-cache) * django-debug-toolbar * gunicorn * celery Paramètres ========== Je vois souvent que la façon d'installer un site django est de copier les sources dans un répertoire, puis de modifier le fichier de conf'. Personnellement, je préfère faire quelque chose du genre : pip install monsuperprojet [modifier un fichier de conf sans toucher aux fichiers que je viens d'installer] monsuperprojet run Pour les paramètres, je distingue trois types de paramètres : * les paramètres qui peuvent communs à plusieurs sites (utilisation de i18n) * les paramètres spécifiques à un site particulier (les fichiers JS/CSS, les composantes, ...) * les paramètres spécifiques à une installation d'un site (paramètres de la base de données) De base avec Django, vous avez un fichier settings.py avec tous ces paramètres. Quand vous créer un nouveau site Django, il faut commencer par recopier un settings.py existant, puis le personnaliser un peu pour le nouveau site (qui doit être versionné). Et quand vous déployez votre site, vous devez le recopier avec la conf' de prod. Vous devez donc recopier le fichier versionné en modifiant certaines valeurs, et recommencer à chaque nouvelle mise à jour. Je propose donc un fichier settings.py générique qui va fusionner trois fichiers de conf' : * un fichier de conf' générique dans djangofloor (suffisant pour avoir quelque chose de fonctionnel, par exemple avec une base SQLite) * un fichier de conf' fourni par votre projet * un fichier de conf' local (pour la vraie base de données), qui sera stocké dans $PREFIX/etc/monsuperproject/settings.py Mais je ne me contente pas d'écraser bêtement le contenu de djangofloor.defaults par monsuperprojet.defaults puis par local.settings : on peut réutiliser certaines variables dans les autres. settings de DjangoFloor : LOCAL_PATH = '/tmp/' MEDIA_ROOT = '{DATA_PATH}/media' STATIC_ROOT = '{DATA_PATH}/static' settings de monsuperprojet : MEDIA_ROOT = '{DATA_PATH}/data' paramètres locaux : LOCAL_PATH = '/var/www/data' STATIC_ROOT = '/var/www/static' Voilà ce que ça donne au final : ... from django.conf import settings ... print(settings.LOCAL_PATH) /var/www/data ... print(settings.MEDIA_ROOT) /var/www/data/data ... print(settings.STATIC_ROOT) /var/www/static Accessoirement, je propose les scripts pour lancer votre projet : djangofloor-manage --dfproject monsuperprojet config djangofloor-manage --dfproject monsuperprojet migrate djangofloor-manage --dfproject monsuperprojet runserver djangofloor-celery --dfproject monsuperprojet worker djangofloor-gunicorn --dfproject monsuperprojet Vous pouvez également en faire de simples : monsuperprojet-manage config monsuperprojet-manage migrate monsuperprojet-manage runserver monsuperprojet-celery worker monsuperprojet-gunicorn Pour déployer notre projet, on peut donc faire : [mkvirtualenv `monprojet`] pip install monprojet [fichier de conf dans ~/.virtualenvs/monprojet/etc/monprojet/settings.py] monsuperprojet-manage migrate monsuperprojet-manage collectstatic monsuperprojet-gunicorn -D Websockets ========== Malheureusement, cette partie ne fonctionne qu'avec Python 2.7. Je distingue quatre types de code : * la partie JS (qui peut parler au Python via du HTTP ou du websocket) * la partie Python dans les vues (reçoit une HttpRequest et renvoie une HttpResponse, peut appeler du Celery) * la partie Python appelé par Celery (peut simplement appeler du Celery) * la partie Python dans les websockets (peut appeler du Celery) Pas évidement de faire parler tous ces composants. Avec DjangoFloor, j'utilise des signaux (un simple nom, auquel on connecte du code JS ou Python). Exemple Python : from djangofloor.decorators import connect @connect(path='demo.my_signal') def my_signal(request, arg): [ some interesting code ] print('blablabla', arg) Quand on a des calculs un peu lourds, on les fait via Celery : from djangofloor.decorators import connect @connect(path='demo.my_signal', delayed=True) def my_signal(request, arg): [ some interesting code ] print('blablabla', arg) Et en JS : df.connect('demo.my_signal', function (options) { alert(options.arg); }); Maintenant, pour appeler ces signaux : from djangofloor.tasks import call, SESSION call('demo.my_signal', request, SESSION, arg='argument') Voilà ce que ça donne en JS : df.call('demo.my_signal', {arg: 'argument'}); N'importe quel code Python ou JS peut appeler n'importe quel signal (qu'il soit JS ou Python). Plusieurs fonctions peuvent s'abonner à un même signal, on peut avoir simultanément du JS et du Python. Quand c'est du Python qui appelle le signal, il peut spécifier la portée côté JS : * aucun client JS ne reçoit le signal, * seule le client JS qui a appelé initialement un signal Python le reçoit, * toutes les sessions JS de l'utilisateur, * toutes les sessions JS. Quand on fait du Python 3, on ne peut pas faire de websockets. Un mode dégradé existe donc : les signaux seront appelés du JS vers le Python par des requêtes HTTP, et cette requête va renvoyer une liste de dictionnaires (autant de signaux à appeler côté JS). Conclusion ========== J'ai juste présenté les deux plus gros trucs de Djangofloor, mais il y a quelques autres subtilités. Le projet est encore loin d'être achevé (notamment la doc :D), mais il m'est déjà bien pratique pour commencer rapidement un nouveau projet web. Le but n'est pas d'avoir LE truc ultime pour des sites hyper personnalisés et à très haute fréquentation, mais d'avoir quelque chose de suffisant pour des sites utilitaires (genre en intranet). Pour finir : le code est dispo sur Pypi et sur Github : https://github.com/d9pouces/django-floor

AltStyle によって変換されたページ (->オリジナル) /