Installation

git clone https://github.com/twidi/django-extended-choices/tree/master

Comment ça marche ?

Avant l'utilisation du plugin

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)

Après l'utilisation du plugin

from extended_choices import Choices
from django.utils.translation import ugettext_lazy as _

STATES = Choices(
    ('ONLINE',  1, _(u'Online')),
    ('DRAFT',   2, _(u'Draft')),
    ('OFFLINE', 3, _(u'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)

Plus clair non ?

Récapitulatif

  1. Vous souhaitez obtenir une liste de tuples, utile pour remplir vos DjangoForm : STATES.CHOICES
  2. Vous souhaitez obtenir la valeur d'une constante : STATES.ONLINE --> 1
  3. Vous souhaitez obtenir le "label" STATES.CHOICES_DICT[1] --> 'Online' ou 'En ligne' selon la langue
  4. Vous souhaitez obtenir le nom de la constante (voir le patch qui suit) STATES.CHOICES_VARNAMEDICT[1] --> 'ONLINE'
  5. Vous souhaitez utiliser une syntaxe "tableau" pour éviter que Aptana vous engueule (voir également patch qui suit - Merci Mickaël Hoareau) STATES['ONLINE']

Version patchée

# -*- coding: utf-8 -*-

class Choices(dict):
    def __init__(self, *choices, **kwargs):
        name = kwargs.get('name', 'CHOICES')
        self.add_choices(name, *choices)

    def add_choices(self, name, *choices):

        CHOICES = []
        CHOICES_DICT = {}
        CHOICES_RDICT = {}
        CHOICES_VARNAMEDICT = {}

        for choice in choices:
            const, value, string = choice
            if not hasattr(self, const):
                setattr(self, const, value)
            else:
                value = getattr(self, const)
            CHOICES.append((value, string))
            CHOICES_DICT[value] = string
            CHOICES_RDICT[string] = value
            CHOICES_VARNAMEDICT[value] = const


        setattr(self, name, tuple(CHOICES))
        setattr(self, '%s_DICT' % name, CHOICES_DICT)
        setattr(self, '%s_RDICT' % name, CHOICES_RDICT)
        setattr(self, '%s_RDICT' % name, CHOICES_RDICT)
        setattr(self, '%s_VARNAMEDICT' % name, CHOICES_VARNAMEDICT)


    def __getitem__(self, key):
        if not hasattr(self, key):
            raise KeyError("Key Error : '" + str(key) + "' not found")

        return getattr(self, key)

Utilisation de django extended choices dans un template.