+
+class Tag(models.Model):
+ """
+ a tag (e.g. document stage) which can be applied to a change
+ """
+
+ name = models.CharField(_('name'), max_length=64)
+ slug = models.SlugField(_('slug'), unique=True, max_length=64,
+ null=True, blank=True)
+ ordering = models.IntegerField(_('ordering'))
+
+ _object_cache = {}
+
+ class Meta:
+ ordering = ['ordering']
+
+ def __unicode__(self):
+ return self.name
+
+ @classmethod
+ def get(cls, slug):
+ if slug in cls._object_cache:
+ return cls._object_cache[slug]
+ else:
+ obj = cls.objects.get(slug=slug)
+ cls._object_cache[slug] = obj
+ return obj
+
+ @staticmethod
+ def listener_changed(sender, instance, **kwargs):
+ sender._object_cache = {}
+
+ def next(self):
+ """
+ Returns the next tag - stage to work on.
+ Returns None for the last stage.
+ """
+ try:
+ return Tag.objects.filter(ordering__gt=self.ordering)[0]
+ except IndexError:
+ return None
+
+models.signals.pre_save.connect(Tag.listener_changed, sender=Tag)
+
+