Apr 302011
 

J’avais plein d’app possible à présenter pour ce billet du mois d’avril. Mais en réfléchissant, je me suis dit que la meilleure app possible à présenter ce moi-si c’était celle qui a été libéré pendant les DjangoCongs à savoir Django-extended-choices.

Et en plus, ce qui est bien, c’est que comme c’est une toute petite app, ça ne sera pas fatiguant du tout d’écrire ce billet.

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

Là c’est tout simple, on la trouve sur github. Et uniquement sur github. Quand à la doc elle tient toute entière dans le fichier Readme.rst qui se trouve lui aussi sur github. (et vous la trouverez aussi en docstring de l’unique classe que contient l’app).

Pour l’installation il suffit ou plutôt il faut forcément, cloner le repo github.

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

A gérer d’une manière propre les Choices que l’on peut avoir à mettre en place dans les fields Django.  Parce qu’il est vrai que la méthode normale, à base de constantes que l’on ne sait pas trop où déclarer et de tuples de tuples, me si elle fonctionne bien, n’est pas super élégante.

L’app permet donc d’encapsuler tout ça dans une belle petite classe

3- Comment ça marche ?

Bon la je vais, sans aucun remords, faire un petit copié/collé de la doc. Parce que l’explication de comment ça marche est très bien faite.

Donc en fait cela marche comme ça :

from extended_choices import Choices

STATES = Choices(
    ('ONLINE',  1, 'Online'),
    ('DRAFT',   2, 'Draft'),
    ('OFFLINE', 3, 'Offline'),
)

class ContentModel(models.Model):
    title      = models.CharField(max_length=255)
    content    = models.TextField()
    state      = models.PositiveSmallIntegerField(choices=STATES.CHOICES, default=STATES.DRAFT)
    related_to = models.ManyToManyField('self', through="ContentToContent", symmetrical=False, blank=True, null=True)

    def __unicode__(self):
        return u'Content "%s" (state=%s)' % (self.title, STATES.CHOICES_DICT[self.state])

    def get_related_content(self):
        return self.related_to.select_related().filter(state=STATES.ONLINE)

plutôt clair non ?

Et cela remplace ce code là :

STATE_ONLINE  = 1
STATE_DRAFT   = 2
STATE_OFFLINE = 3

STATE_CHOICES = (
    (STATE_ONLINE,  'Online'),
    (STATE_DRAFT,   'Draft'),
    (STATE_OFFLINE, 'Offline'),
)

STATE_DICT = dict(STATE_CHOICES)

class ContentModel(models.Model):
    title      = models.CharField(max_length=255)
    content    = models.TextField()
    state      = models.PositiveSmallIntegerField(choices=STATE_CHOICES, default=STATE_DRAFT)
    related_to = models.ManyToManyField('self', through="ContentToContent", symmetrical=False, blank=True, null=True)

    def __unicode__(self):
        return u'Content "%s" (state=%s)' % (self.title, STATE_DICT[self.state])

    def get_related_content(self):
        return self.related_to.select_related().filter(state=STATE_ONLINE)

Personnellement, je trouve que la notation pointée  STATES.CHOICES ou  STATES.DRAFT est bien bien plus clair que la notation précédente.

Conclusion

Une petite app qui ne fait qu’une chose mais qui le fait bien. A utiliser de partout donc. (Il ne manque juste que des tests ..:) ) .

  One Response to “Django-extended-choices, l’app qui te donne le choix (mais pas la date)”

  1. Manque peut être la gestion de l’i18n sur les constantes.

Sorry, the comment form is closed at this time.