Djangocong 2.0, le bilan

4 jours après la fin des Cong, il est temps pour moi de faire le bilan de cette deuxième est, en tout cas à mon sens, excellente édition.

Les Congs en quelques chiffres :

  • 11 conférences le matin
  • 12 slots de barcamp l’après-midi
  • 1 app releasée durant les Congs
  • 1 doc de bonne pratique lancée
  • 75 personnes le samedi matin dans l’amphi, à écouter les conférences (un peu moins le dimanche matin, après la soirée arrosée, parce que comme là dit un illustre inconnu : ‘ce matin, on a 50% de perte)
  • 3 repas complétement pris en charge par l’organisation
  • un peu plus de 100 dosettes de Senseo utilisés sur les deux jours (mais qu’une dizaine de sachet de thé, on le sait tous, le café est supérieur au thé)
  • 200 litres d’eau bus, au bas mot, parce que dans le sud, il fait chaud, Cong !
  • Quelques bonnes dizaines de coup de soleil, cadeau surprise pour ceux qui n’ont pas l’habitude du vrai soleil du vrai sud.
  • 36 litres de bières (edit : j’avais oublié les 6litres de guinness) et 20 litres de vin bu lors des 6h qu’à durer la soirée du samedi soir. Et pourtant tout le monde est rentré sur ses jambes.
  • Un nombre de kilo de paella engloutis par nos estomacs,  qui fait juste peur. Comme quoi les poneys, ils ont bon appétit.
  • un article dans Linux Magazine dans le prochain numéro.

Les Congs du point de vue d’un organisateur.

La deuxième édition fut l’occasion d’essayer d’être plus pro dans l’organisation des choses. Et je pense qu’on a fait plus qu’essayer.

  • Plus de salles dont un amphi bien équipé niveau son (Merci encore à l’école centrale de Marseille nous avoir accueilli pendant ces deux jours).
  • Plus de préparation au niveau des repas. On a remplacé les réservations dans de multiples restos par des plateaux repas et des sandwitch livrés sur site, pour gagner du temps et permettre de continuer en mangeant les discussions entamées pendant les confs.
  • Une vrai préparation pour la soirée du samedi (à la Boate) et pas juste un ‘on va sur le vieux port et on trouve un resto comme l’année dernière).
  • Quelques choix un peu clivant comme des durées de conf courtes ou du #Nowificonf pendant une partie des Congs.
  • Moins de trajet dans ma voiture pour chercher les gens perdus ou les ramener. Marseille commence à priori à être connu de tous et il n’y a plus de femme enceinte parmi les présentes :).
  • Encore plein de points à parfaire ou à juste faire (comme prévoir l’impression des badges en avance et les donner le premier matin, à l’arrivée. Ou prévoir un vrai carnet de route de l’accompagnant avec activités et truc à faire pour ne pas lâcher les gens comme ça et qu’ils s’ennuient pendant deux jours).

Les congs d’un point de vue perso.

Vivement la troisième édition. Comme les deux premières fois, la fin des Congs arrivant, un grand sentiment de vide se fait sentir et à peine le dimanche soir arrivé, l’envie d’être déjà à l’année prochaine, de pouvoir discuter à nouveau en IRL avec des gens que je ne vois parfois qu’une fois par an.
D’un point de vue perso, l’année dernière avait été une grande claque technique dans ma figure. Deux jours de conférences non stop, ça en met plein les mirettes.
Cette année, malgré le fait qu’il y est moins de conférences ce fut encore mieux. Les confs auxquelles j’ai pu assister m’ont en effet fait découvrir plein d’outil qu’il va falloir que je test, mais les barcamps ont permis d’échanger pour de vrai, de commencer même pour certaines sessions à poser les premières pierres de quelques choses (je pense là a Geek sans Frontière par exemple).

Mais ce n’est pas tout. L’un des points qui fait que cette deuxième édition fut immensément mieux que la première c’est que cette année la partie ‘non technique’ a été pensée et organisée. Et autant sur des découvertes techniques, on peut imaginer les faire par IRC / billets de blog, autant rencontrer les gens et se rendre compte qu’on les apprécie, pour de vrai, hé ben, y a pas à dire, il faut être dans la même pièce.

On mange difficilement de la barbe à papa rose sur IRC. Apprendre le GO, c’est aussi un peu compliqué. Et je ne parlerais même pas de jouer à ‘il était une fois’ avec Kael, Cyberj et Exirel. Ou de tenter de survivre à une partie de Pandémie. Et comme ArmagnacOverIP n’existe pas encore, on a encore besoin que dzen ramène sa bouteille dans son sac pour y gouter (je ne t’oublie pas brutasse, ta chartreuse était très bonne aussi:) ). C’est tout ces moments là. Tout ces moments partagés qui font que pour de vrai, DjangoCong 2.0, putaing, c’était terrible.

Et à l’année prochaine, pour d’autre aventure et une djangoCong 3.0

quelques liens :

 

Petites apps … petites mais costaudes

Pour ce mois de mars, je vais parler non pas d’une seule mais de deux petites apps. Deux apps parce que les apps sont tellement petites que l’on va m’accuser de tirer au flanc si je ne parle que de l’une d’entre elles. Mais que d’un autre cotés, ce n’est pas parce qu’elles sont petites qu’il ne faut pas en parler.

django-generic-aggregation

 

Qui n’a jamais utilisé les agrégat dans Django ? C’est quand même super utile. Et qui n’a pas ralé sur le fait que zut alors… Saperlipopette même, on ne pouvait pas utiliser les agrégat sur les Generic FK ?

Et c’est là qu’arrive django-generic-aggregation. Qui permet justement de le faire.

Concernant l’installation, trois moyens :

Quand à la doc, vous aurez droit à la page de pypi qui est aussi la page de doc de github. Bon après, il faut bien dire que l’app n’est pas super compliqué à comprendre.

Et au pire, il y a le code des tests. Une petite précision toutefois concernant la doc, la page readthedoc de l’app renvoie pour l’instant sur un 404 readthedoc (un 404 en ASCII ART d’ailleurs)

Ensuite à l’utilisation c’est tout simple, un petit exemple, tiré de la doc :

from generic_aggregation import generic_annotate
from django.db.models import Sum, Avg

# assume a Food model and a generic Rating model
apple = Food.objects.create(name='apple')

# create some ratings on the food
Rating.objects.create(content_object=apple, rating=3)
Rating.objects.create(content_object=apple, rating=5)
Rating.objects.create(content_object=apple, rating=7)

>>> aggregate = generic_aggregate(Food.objects.all(), Rating.content_object, Sum('rating'))
>>> print aggregate
15

>>> aggregate = generic_aggregate(Food.objects.all(), Rating.content_object, Avg('rating'))
>>> print aggregate
5

Pour la petite histoire, j’ai découvert cette app en testant django-simple-ratings une autre app du même monsieur.

django-exposure

 

La encore une petite app toute bête qui permet de resizer des images avant de les afficher. Les images redimensionnées sont stockées en mémoire et il y a même une gestion de cache.

La doc est présente sur packages.python.org et elle explique bien la manière de l’utiliser. Après pour vraiment comprendre, vive les sources.

Quand à l’installation, vous pourrez soit utiliser :

un petit pip install django-exposure
ou une récupération d’un tar.gz sur bitbucket
ou même un hg clone

L’utilisation en elle même est très simple. Il suffit en effet d’utiliser le filtre |resize en lui donnant trois paramêtre, Width, Height et Crop.

Crop peut prendre 5 valeurs de 0 à 5 suivant le crop que vous voulez mettre en place ( 0 étant pour un crop centré).

 

Pour rester dans le même sujet, je ne peux finir ce billet sans parler de django-thumbnail-works qui sert comme son nom l’indique à gérer les thumbnail. Le principe étant de là, gérer cela directement au niveau de l’ImageField. Mais je ne peux vous en dire plus, je n’ai pas eu le temps de la tester.

DjangoAstuce : masquer certains champs des settings dans la vue de Debug

Par défaut, la vue de DEBUG affiche toutes les settings. Heureusement pour nous, gentils petits djangonautes, les password des BD mais aussi le password du user emails sont remplacés par des belles petites ***.

 

Mais comment faire pour masquer d’autre champs ? Comme des champs de KEY d’API ou de password divers ? Parce qu’après tout, il peut arriver de devoir en stocker, et de vouloir les cacher à certains des yeux qui pourraient voir la vue de DEBUG.

 

He ben, encore une fois, django a tout prévu. Il suffit en effet que le nom de votre constante contienne soit :

  • SECRET
  • PASSWORD
  • PROFANITIES_LIST
  • SIGNATURE

 

Pour que dans les vues de DEBUG, leur valeur soit remplacé par des ***

 

Et bien entendu, cela marche aussi pour les key des dictionnaires que vous pourriez déclarer dans vos settings (l’exemple parfait étant celui qui sert de configuration pour les BD).

Django-mockups, l’application mi moquette, mi ketchup

Malgré le fait que le mois de février ne fasse que 28 jours, malgré le fait que j’ai maintenant une petiote qui gazouille gentiment en me regardant avec ses grands yeux bleus, malgré le fait que les journées au boulot ne se finissent jamais, même le week-end, je réussi donc la prouesses de sortir à temps la django app du mois de février (et de tenter de vous préparer des petits trucs cools pour ceux qui viendront aux djangocongs, je dis ça, j’en dis pas plus) (et parenthèse bis, je suis très fier de mon titre)

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Alors on le trouve sur sa page pipy mais aussi sur sa page github.
Pour l’installation, comme souvent on à le choix entre :

  • passer par pip avec un petit pip install django-mockups
  • passer par easy_install
  • passer par un git clone

Quand à la doc, elle est générable quand on installe le paquet sinon la page pipy (mais aussi la home page du projet) en contient une bonne partie. Elle est, en l’état, il faut bien le dire, un peu limité et d’ailleurs l’auteur le dit lui même dans la dernière partie. C’est dommage, mais en attendant une doc plus précise, il y a toujours la possibilité de lire le code.

2- Mais au fait, à quoi ça sert ?

A générer des données. De grosse masse de données de test générées aléatoirement pour remplir vos bases de tests et rendre vos tests plus facile.

3- Comment ça marche ?

En fait on peut utiliser django-mockups de deux façons. Soit en utilisant une ligne de commande soit en mettant un place un script qui va utiliser les classes fourni par l’app et vous permettra de faire bien plus de choses que la simple ligne de commande.
Vous pourrez entre-autre :

  • définir combien de données par modèles vous voulez générer.
  • décider si vous voulez générer ou pas des données de table reliés par fk ou m2m aux tables que vous configurez dans mockups, sachant que bien entendu vous pouvez décider lesquelles des fk vous voulez générer.
  • Pour les m2m, choisir combien de relation vous allez vouloir créer, en pouvant utiliser un intervalle.
  • Spécifier lorsque que vous voulez, au milieu de votre masse de données générées, insérer des données bien précises.

4 Conclusion

Je découvre à peine django-mockup depuis quelques jours. Mais déjà je lui vois de multiples utilisations possibles, que ce soit pour tester des algos de recherche dans une grosse masse de données ou faire des tests de charges plus réalistes qu’auparavant.

Django-admin-tools, la django app de janvier, presque à l’heure

Jusqu’à présent j’avais toujours réussi à poster mes billets de django app à l’heure. Mais là, là, j’ai une excuse. Je suis devenu papa le 31 janvier. Du coup, je n’ai vraiment pas eu le temps pour écrire mon billet de django app (les raleurs qui me diront que j’avais tout les jours d’avant le 31 pour écrire mon billet auront raison.. mais chut, j’ai une excuse, c’est tout).

Ce mois-ci (enfin le mois dernier quoi), je vais parler d’une partie de django dont je ne parle pas assez l’admin, en vous présentant django-admin-tools.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Où on le trouve sur sa page bitbucket sur laquelle vous trouverez aussi tout plein de screenshoot (que je reproduis ici en partie), une mini doc et un lien vers une doc très très complète.

Quand à l’installation vous pouvez soit :

  • cloner le repo puis faire un python setup.py install
  • utiliser easy install : easy_install django-admin-tools
  • utiliser pip : pip install django-admin-tools
  • simplement mettre le repertoire admin_tools dans votre python path

Quand à la doc, elle est présente sur readthedocs.org et est vraiment très bien faite. bien fournie et claire.

2- Mais au fait, à quoi ça sert ?

Django-admin-tools va vous permettre de customiser votre admin django.

Vous allez pouvoir des petits dasboards en page d’accueil, personnalisable et drag and dropable et foldable. Vous allez aussi pouvoir avoir un menu horizontal et une gestion des bookmarks. Les menus pourront être constitués de sous menus, de liens finaux ou de menus construits automatiquement à partir de  la liste des app (moins celles que l’on décide d’exclure).

3- Comment ça marche ?

Dans tout les cas, il y a une config par défaut. Si on veut changer la config des dashboard ou du menu, il faut générer un module python ( qui par défaut sera celui qui donne la config par défaut), le modifier et indiquer que l’on veut l’utiliser. On peut aussi modifier le thème CSS qui sera utilisé.

Pour le menu :

  • python manage.py custommenu

ou

  • python manage.py custommenu somefile.py

puis :

  • ADMIN_TOOLS_MENU = ‘yourproject.menu.CustomMenu’

pour le dashboard, même chose :

  • python manage.py customdashboard

ou

  • python manage.py customdashboard somefile.py

puis

  • ADMIN_TOOLS_INDEX_DASHBOARD = ‘yourproject.dashboard.CustomIndexDashboard’
  • ADMIN_TOOLS_APP_INDEX_DASHBOARD = ‘yourproject.dashboard.CustomAppIndexDashboard’

4 Conclusion

Je dois bien avouer que je pense sous utilisais l’admin django. Je suis toujours à refaire des trucs en espace non admin alors que l’admin offre pourtant des possibilités immenses, pour très peu de temps passés. La découverte de django-admin-tools me conforte dans l’idée qu’il faut que je me force à utiliser plus souvent l’interface admin. Et donc à tester de nouvelles app d’extension de l’admin.

M2m, tout petite astuce

Il faut parfois utiliser des m2m. Dans django, il y a deux moyens de les utiliser. Soit d’une façon simple, en déclarant juste un ManyToManyField soit en passant par une table explicite grâce à l’argument through.

L’argument through permet d’avoir une table explicitement déclaré que l’on peut donc manipuler avec l’ORM.

Mais si on utilise la méthode commune, celle où c’est django qui fait tout, on pourrait avoir l’impression que l’on a alors, plus accès à cette table de jointure. Ce n’est pas utile allez vous me dire, on s’en fout, la seule info que l’on manque c’est la pk des tuples.

C’est vrai dans la plupart des cas. Mais comment faire si vous veniez à avoir besoin de pouvoir mettre la main sur ces PK ? Si par exemple vous voulez synchroniser des choses ??

Et bien, les choses sont bien faites en django. Il existe en effet une données membres through qui permet de récupérer la table créer automatiquement dans django.

Un petit exemple (en reprenant celui de django)

class Topping(models.Model):
# ...
class Pizza(models.Model):
# ...
    toppings = models.ManyToManyField(Topping)

pour avoir accés à la table qui relie les Pizza au Topping il suffit de faire :

Pizza.toppings.through

et donc pour filter il suffit de faire :

Pizza.toppings.through.objects.filter (…. )

Et voilà.

Django-easy-maps, c’est comme google maps, mais dans ton site

Cette année se finira comme elle a commencé, en bossant et avec beaucoup moins de temps que ce que j’aimerais en avoir. Il y a pas à dire, il faut vraiment que je me remette à jouer au loto, histoire de pouvoir rêver à un jour, avoir tout le temps que j’aimerais avoir.

Mais ne pas avoir de temps n’est pas une raison pour ne pas perpétuer la tradition des django apps du mois. Surtout que cela fait déjà 16 mois que je tiens, et que tout les mois, qu’il fasse chaud ou froid, que les zombies ou les ET menacent de nous éradiquer ou que le tout derniers MMO à la mode sorte sa béta, je publie un billet de présentation de django app.

Et ce mois ci, je vais vous parler d’une app que j’ai découvert il n’y a que quelques dizaines jours mais qui est bien sympathique (il est même possible que je l’utilise dans un contexte de business).

Cette App c’est donc django-easy-maps.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Vous trouverez django-easy-maps sur sa page bitbucket (enfin un projet qui a compris qu’il fallait utiliser mercurial parce que rien n’est mieux que mercurial).
Mais vous aurez aussi le droit à une page pypi (à l’heure ou j’écris, la version sur pypi est la 0.7).

Pour l’installation, vous avez deux méthodes :

  • un petit hg clone ( hg clone https://VOTREUSER@bitbucket.org/kmike/django-easy-maps )
  • un pip ou un easy_install suivant votre préférence.

La doc, elle, tient dans le fichier Readme du projet et dans les commentaires du code. Mais il faut bien avouer que vu la taille de l’app, c’est bien suffisant pour comprendre comment l’utiliser. Si vous voulez comprendre comment elle marche, la par contre, il faudra lire le code.

2- Mais au fait, à quoi ça sert ?

Elle sert à afficher une carte, directement tiré de google maps, qui montre une adresse.

Vous donnez l’adresse que vous voulez voir apparaître à un templatetags et au moment du rendu, vous voyez apparaître un joli composant google maps, avec zoom, déplacage de la carte possible, etc etc. Et en plus, sans avoir besoin d’API Key google ou autre. Plutôt cool nan ?

On peut de plus définir les tailles de la carte, passer un template custom ou utiliser le cache template django.

3- Comment ça marche ?

Tout d’abord il faut penser à installer geopy qui est une dépendance obligatoire. (par pip ou easy_install).

Ensuite, c’est tout simple. On commence par loader le bon templatetags :
{% load easy_maps_tags %}

et ensuite on demande l’affichage de la carte :

{% easy_map “Russia, Ekaterinburg, Mira 32” 300 400 %}

Si on veut personnaliser, on peut, en faisant par exemple :

{% easy_map address 200 200 5 using ‘map.html’ %}

La syntaxe complète du templatetags étant :

{% easy_map < address > [ < width > < height >] [< zoom >] [using < template_name >] %}

Vu mes explications, vous pensez peut-être qu’il n’y a pas de modèles BD. En fait si. L’app stocke en effet la longitude et latitude en BD pour ne pas avoir à les recalculer à chaque fois.

4-Conclusion

Django-easy-maps est une petite app, qui fait pas forcément beaucoup de chose mais qui les fait bien. Et ça j’aime.

Une précision importante, elle fonctionne avec South, donc si vous avez mis en place South pour votre projet django, un simple ./manage.py migrate easy_maps à la place syncdb et ça roule …

5-Conclusion bis

C’est donc avec django-easy-maps que je termine cette année de django-apps du mois. J’espère que certains billets vous ont été utile et vous ont fait découvrir des apps que vous utilisez maintenant quotidiennement.

En tout cas, je vous souhaite un très bon réveillon 2010 et vous dit à l’année prochaine, en espérant que j’aurais le temps de tester l’app que j’ai prévu de vous présenter en janvier qui sera, cette fois-ci, une app d’une toute autre dimension (si j’ai le temps).

Quelques nouveautés de django 1.3

Comme l’indique la roadmap officielle, django 1.3 c’est pour dans bientôt. La bêta avec freeze des fonctionnalités, c’est pour dans 15 jours et la release, pour le 17 janvier. Tout bientôt donc.

Il a de plus déjà été annoncé qu’il n’y aurait pas de nouvelles fonctionnalités dans cette version, que ce serait surtout une release de bugfix et de ‘on finit les choses que l’on a annoncé depuis X années et qu’on a jamais finies’… Enfin, il y a quand même quelque trucs très sympa, voir très très sympa que je vais rapidement lister

Mécanisme de logging

C’est l’un des deux points dont parle la new de la roadmap. A savoir intégrer la lib standard de logging python dans Django. C’est clairement une fonctionnalité sympa, mais il faut avouer que ce n’est pas très très sexy.

Les generics view en mode class based.

Cela permettra à Django de se rapprocher de certains framework web bien connu, avec 2 R dans leur nom (et un O). Et cela devrait aussi simplifier l’utilisation des generics views. De quoi peut-être donner envie à plus de gens de les utiliser. (doc du site officiel)

Choisir le comportement à adopter lors d’un delete d’une FK.

Jusqu’à présent, lorsqu’on supprime un enregistrement en BD et que cet enregistrement était lié à d’autre enregistrement par une FK (par exemple une fonction pour des contacts dans une entreprise), la suppression se faisait en cascade, sans possibilité de modifier cela (à moins d’aller bidouiller un peu profond). Du coup, op vous supprimiez la fonction Secrétaire et c’est toutes vos secrétaires qui passaient à la trappe .. Là, on va enfin pouvoir choisir entre les choix suivant :

  • CASCADE (le fonctionnement actuel)
  • PROTECT (la suppression ne se ferra pas)
  • SET_NULL (la FK sera mise à NULL)
  • SET_DEFAULT (la FK sera mise à la valeur par défaut)
  • SET ()  sera mise à la valeur qui sera passé à SET ( ce pourra être un callable )

Et ça, c’est tout simplement génial !!!  (doc sur site officiel concernant le on_delete des FK)

Préparez un solide alibi, parce que nous savons que vous avez un mobile, un django-mobile

J’ai déjà fait un billet parlant d’une app de monsieur gregmuellegger, à savoir celui sur les websockets. Mais le monsieur étant prolifique, je me vois ‘obligé’ d’écrire à nouveau sur une de ses apps, à savoir django-mobile.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Alors on trouve django-mobile à la fois sur :

Pour l’installer donc, un petit coup de

  • easy install ou apparenté
  • git clone

et le tour est joué.

La doc quand a elle, est bien fournie. Avec une description ‘théorique’, des exemples précis et une explication pour chacune des variables de configuration utilisable

2- Mais au fait, à quoi ça sert ?

Comme son nom l’indique, django-mobile permet d’avoir un mode de visualisation mobile pour son site django. Mais en fait, pas seulement. Il permet en fait d’avoir X modes de visualisation pour son site :  mobile, Ipad, sans image, etc ….

3- Comment ça marche ?

Django-mobile fonctionne avec le concept de ‘flavour’.
Vous commencez par définir plusieurs ‘flavour’ pour votre site, tout simplement en les listant dans votre settings.py.

Chaque flavour se défini par son nom et surtout son jeu de template propre qui sont tous rangé dans un ou des sous-répertoires ayant le nom de la flavour en question.

Ensuite il suffit de passer d’une flavour à l’autre. Pour cela deux façon soit c’est une détection automatique (pour passer en mode mobile) soit vos visiteurs peuvent passer d’une flavour à une autre. La valeur de la flavour courante sera alors stockée comme une variable de session (dont le nom est paramétrable)

Le tout fonctionne assez simplement en se basant sur :

  • un middleware qui détecte automatiquement si vous venez d’un terminal mobile ou pas
  • un loader qui rajoute le nom de la flavour en répertoire préfixe pour vos templates
  • deux context processor qui injectent l’un le nom de la flavour courante et l’autre indique si on est en mode mobile ou pas
  • un middleware qui permet de changer la flavour courante.

Django-mobile, en plus d’être simple est pas mal customisable, presque à l’excès. On peut configurer le nom du paramètre de ssion qui stockera la flavour courante choisi par vos visiteurs, le nom du paramètre GET qui permet de changer la flavour courante. On peut également désactiver la possibilité pour l’utilisateur de choisir sa flavour ou choisir si on veut rajouter un répertoire préfix de plus à tout les répertoires de flavour (pour les ranger proprement tous dans un répertoire flavour par exemple).

Que du bon donc, et une petite app à utiliser sans modération (va falloir que je pense à l’intégrer pour histoire de rolistes tiens ). Et puis en plus, j’ai même pu faire un jeu de mot dont je suis excessivement fier dans mon titre de billet…:)

Django-qsstats, parce qu’en vrai,on adore tous faire des stats.

Ce mois-ci, j’aurais pu écrire plusieurs django-app du mois. Si j’avais eu le temps. Mais bon, le jour où j’aurais le temps, ça se saura. Du coup, alors que l’horloge tourne et qu’il ne me reste plus qu’un jour et demi pour écrire ma django app du mois et mon polargeek, j’ai décidé d’écrire ma django-app du mois pour parler de django-qsstats, une petite application comme je les aime.

C’est à dire, qui ne fait qu’une chose, une toute petite chose, mais qui la fait bien. Et qui du coup est facilement intégrable, sans remord.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

On la trouve sur sa page github. Il me semble bien que le seul moyen d’installation soit à travers github. Mais bon, cloner un repository git hub, ce n’est pas le plus compliqué.

La doc, elle, se limite au fichier Readme et à la lecture des tests. Mais bon, honnêtement, cela suffit.

Par contre attention, en plus de nécessiter django 1.1 à minimal, cette petite app a besoin de python-dateutil (une petite librairie qui ajoute pas mal d’extension plutôt puissante à datetime, si vous ne connaissez pas, je vous recommande vivement d’aller jeter un oeil (mais pas les deux, après vous ne pourrez plus lire la doc … ) )

2- Mais au fait, à quoi ça sert ?

A presque rien, mais c’est bien utile.:) Lorsqu’on veut faire un minimum de stats, de comparaison ou autre, on se retrouve assez vite à vouloir trouver combien il y a eu de nouveaux articles la semaine dernière, combien d’histoires ont été écrites par des rôlistes durant le mois dernier, ou d’utilisateur enregistré les 6 derniers mois…

Faire cela est très simple, un petit queryset puis des petits filters. C’est très simple, mais bon, c’est rapidement chiant, et puis c’est pas très DRY.

Donc on se retrouve assez vite à faire des petits fonctions pour avoir les dates du mois en cours, ou d’un mois précis..

Où alors on se dit que quelqu’un à surement du le faire à notre place, on cherche un peu et on tombe sur django-qsstats.

3- Comment ça marche ?

C’est vraiment tout simple. Il suffit de mettre l’app dans son python-path. Ensuite un peu l’utiliser. Rien à faire de plus. Même pas de syncb vu que c’est une app sans model. (il y a un fichier models mais il n’est là que pour les tests).
Ensuite, ben un exemple sera plus parlant (je reprend l’exemple du site officiel)  :

from django.contrib.auth import User
import qsstats

qs = User.objects.all()
qss = qsstats.QuerySetStats(qs, 'date_joined')

print '%s new accounts today.' % qss.this_day()
print '%s new accounts this month.' % qss.this_month()
print '%s new accounts this year.' % qss.this_year()
print '%s new accounts until now.' % qss.until_now()

Vous le voyez, c’est assez facile. On construit son queryset et ensuite on le passe à qsstats en lui indiquant le champ date qui devra servir au filtrage.

Déjà là, ça serait pas mal. Mais il y a mieux. Il existe la fonction time_series qui permet de récupérer une liste de valeur. Par exemple :

from django.contrib.auth import User
import datetime, qsstats

qs = User.objects.all()
qss = qsstats.QuerySetStats(qs, 'date_joined')

today = datetime.date.today()
seven_days_ago = today - datetime.timedelta(days=7)

time_series = qss.time_series(seven_days_ago, today)
print 'New users in the last 7 days: %s' % [t[1] for t in time_series]

qui donnera :
New users in the last 7 days: [3, 10, 7, 4, 12, 9, 11]

Si cela itère par jour, ce n’est pas magique, c’est parce jour (enfin day) est l’argument step par défaut. Mais on peu bien entendu changer la taille du pas.

Enfin, par défaut, toutes les fonctions utilise Count pour calculer les résultat. (et quand je dis Count, c’est effectivement la class Count des Aggregat de django) Mais on peut changer ce comportement en donnant une valeur au paramètre agregate_class du QuerySetStats.

4-Conclusion

Comme je le disais en introduction, j’aime beaucoup les petites apps qui font des petits trucs, mais qui le font bien. C’est bien souvent plus utile que les grosses apps qui font tout et le café et qui sont bien plus difficile à intégrer (ceci n’est pas une critique de pinax hein, ne me faite pas dire ce que je n’ai pas dit).

Donc j’aime forcément, beaucoup qsstats.

Une petite information un fork de qsstats a été créé, sur bitbucket (et que vous trouverez sur pypi). Il s’appelle django-qsstats-magic. Il rajoute la gestion des heures et des minutes, une optimisation qui fonctionne avec mysql et modifie des trucs en interne. Mais effectivement, je n’ai pas poussé plus loin mes investigations.

Monkey Patching, une petite astuce

Vous connaissez surement cette astuce de dev qu’est le Monkey Patch (voir article wikipedia). En résumé, ça permet d’étendre ou de modifier le code sans modification du code original. Bien entendu, on ne peut monkey patcher que des langages dynamiques.

En python, pour monkey patcher une classe, par exemple, on fait :

class NewKlass :
…..
…..

from project.apps import modtest
modtest.Klass = NewKlass

Rien de bien difficile. Mais compliquons un peu les choses. Imaginons que notre classe Klass soit une classe qui nous convient en partie, mais pas complétement. Certaines fonctions nous conviennent parfaitement, mais pas d’autre. Et pour corser le tout, il faudrait qu’on rajoute des données membres à la classe. On ne peut donc pas ‘juste’ monkey patcher les fonctions qui ne nous plaisent pas…

Comment faire ?

Il faudrait pouvoir dériver de la classe qu’on veut monkey patcher, avant de la monkey patcher.. Mais ce n’est surement pas possible non ? Et ben si. Et c’est très facile.

On commence par écrire notre nouvelle classe :

from project.apps.modtest import Klass as OldKlass

class NewKlass(OldKlass) :
….
….

et ensuite on monkey patch, comme précédemment :

from project.apps import modtest
modtest.Klass = NewKlass

Une précision par contre, lorsque vous allez définir les fonctions dans NewKlass, vous alelz peut être vouloir appeler la fonction mère de la fonction que vous définissez (par exemple dans les models django, on appelle souvent le save de la fonction mère, dans le save de notre fonction)

sauf que là, il faut faire attention si vous faites :

class NewKlass(OldKlass) :
….
….

    def save(self, *args, **kwargs) :
        super( NewKlass,self).save(*args, **kwargs)

vous avez droit à une bonne récursion infinie. Parce que oui, la fonction mère de NewKlass c’est OldKlass, qui est en fait NewKlass, vu qu’on la monkey-patchée.

Il faut donc appeler utiliser la classe grand-mère de NewKlass, en faisant un

class NewKlass(OldKlass) :
….
….

    def save(self, *args, **kwargs) :
        GrandMereNewKlass.save(self,*args, **kwargs)

Petit Rajout : On me demande qui est GrandMereNewKlass. GrandMereNewKlass est en fait MereOldKlass. ou comme le propose @daks_ OldKlass.__base__ (D’ailleurs la question de ‘est ce que ça marche avec de l’héritage multiple qu’il pose dans le même tweet, reste entière 🙂 ).

Bon alors, on sait tous que le monkey Patching, c’est à utiliser avec de grande précaution. Et que bidouiller ainsi en dérivant de la classe que l’on veut monkey patchée c’est tout sauf safe. Mais bon, c’était la question du jeudi de la semaine dernière. ‘Peut-on monkey patcher une classe par une de ses classes filles ?’.

La réponses est donc oui.

Mais ce n’est pas à mettre entre toutes les mains.

Django-taggit, le tag est mort, vive le tag ..

J’ai déjà fait, il y en fait 11 mois, un billet de la django app du mois sur une app de tag, django-tagging. Lorsque je l’ai testé, django-tagging était à la version 0.3. Aujourd’hui, elle est version 0.3.1. Et les derniers commit remonte à janvier 2010 ( ce sont ceux ayant aboutis à la version 0.3.1)

Je me suis donc dit, qu’il était peut-être tant de revenir sur le sujet et de présenter une autre app django, sur le même sujet, qui même si pour l’instant présente quelques lacunes comparée à django-tagging, me semble prometteuse.

Et cette app, c’est, roulement de tambour…., django-taggit d’Alex Gaynor (un trublion bien connu pour ceux qui font du django)

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Alors on le trouve tout simplement sur sa page Pypi ou sur sa page github d’ailleurs

Pour l’installation rien de plus simple :

  • un easy_install ou un pip
  • un git clone

Pour la doc, là il n’y a vraiment rien à redire, le projet offre une doc très bien fournie sur readthedocs.org.

2- Mais au fait, à quoi ça sert ?

Tout simplement à taguer des objets. Exactement comme django-tagging donc. Vous allez pouvoir taguer vos objets, filtrer les objets en fonction des tags qu’ils ont ou trouver des objets similaires de par leur tag.

Vous allez aussi pouvoir modifier légèrement la mécanique interne. Par exemple si utiliser des generics key ne vous plait pas, tout est prévu pour que vous puissiez simplement les remplacer par des foreign key. Vous pourrez aussi changer d’autre mécanismes comme le model utilisé pour sauver les Tags.

3- Comment ça marche ?

Tout d’abord il faudra que vous ajoutiez, pour chaque models que vous voulez rendre ‘tagable’ un manager de tag. (Pour ceux qui se souviennent django-tagging permet de taguer directement des instances de models, sans modifier la classe Model en question).

Ca peut paraître un peu lourd et ça rend l’app assz intrusive, mais bon, c’est comme ça. Et puis du coup ça permet, il faut bien l’avouer d’avoir une écriture plus fluide et plus ramassé de son code. Nul besoin de toujours passer par la classe Tag en filtrant sur l’objet dont l’on veut récupérer les tags. Un simple object.tags suffit pour avoir tout ses tags.

Facilité d’utilisation ou intrusivité, à vous de choisir, django-taggit, lui  à choisit. (Et bon, au pire, un bon petit contribute_to_model devrait permettre une extensibilité moins intrusive).

Pour ajouter les tags, les syntaxes possible sont à peu près les mêmes que celle de django-tagging, à savoir (l’image est une capture d’écran d’une partie de la doc) :

Un truc à ne pas oublier, django-taggit utilise des many to many. Donc, n’oubliez pas le save_m2m si vous utilisez des forms.

Ensuite, vous pourrez bien entendu supprimer des tags, les lister, filtrer des objets en fonction de leur tags ou avoir une liste des objets similaires. C’est une vrai liste qui est classée par ordre de similarités.

4- Une app peut en cacher deux autres.

Là, à cette instant de votre lecture vous vous dites peut-être ‘Mais mer..mince alors, il manque des trucs comparés à django-tagging, il n’y a même pas de templates tags d’affichage’.

Et vous auriez raison. Sauf que, sauf que… Il y a des applications qui étendent django-taggit à savoir :

5- Au final

Vu le statut de quasi moribond de django-tagging comparé à la vigueur actuelle de django-taggit, je pense vraiment que si vous avez besoin d’une application qui gére les tags, django-taggit est un meilleur choix. Et puis, je trouve ça rassurant qu’il y ait des applications externes pour étendre django-taggit.