from datetime import datetime from django.db import models from django.utils.translation import ugettext as _ class Collection(models.Model): name = models.CharField( max_length=255, verbose_name=_('name'), unique=True) shortname = models.CharField(max_length=30, verbose_name=_('shortname')) def __str__(self): return '%s' % self.name class Meta: abstract = True ordering = ['name'] class Item(models.Model): TARGET_MODEL = None TARGET_VERBOSE_NAME = None # status choices CREATED = 'created' STATUS_CHOICES = ((CREATED, _('New')), ) DEFAULT_CHOICE = CREATED name = models.CharField(max_length=255, verbose_name=_('name')) achievement = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('achievement')) achievement_max = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('out of')) def __str__(self): return '%s' % self.name @classmethod def on_class_prepared(cls): """ Add new field 'collection' which is a link to TARGET_MODEL. Add new field 'status' which is a list of choices. With CREATED. """ target_field = models.ForeignKey( cls.TARGET_MODEL, related_name=cls.RELATED_TARGET_NAME, verbose_name=_(cls.TARGET_VERBOSE_NAME)) target_field.contribute_to_class(cls, 'collection') status_field = models.CharField( max_length=30, choices=Item.STATUS_CHOICES + cls.STATUS_CHOICES, default=cls.DEFAULT_CHOICE, verbose_name=_('status')) status_field.contribute_to_class(cls, 'status') # check that no other same item name on same collection exists cls._meta.unique_together = (('collection', 'name'), ) class Meta: abstract = True ordering = ['name'] class Timeline(models.Model): """ Keep changes on collection. For an example, a game cretion date. Or when you completed a game. """ TARGET_MODEL = None TARGET_VERBOSE_NAME = None STATUS_CHOICES = Item.STATUS_CHOICES DEFAULT_CHOICE = Item.CREATED date = models.DateField(default=datetime.now, verbose_name=_('date')) @classmethod def on_class_prepared(cls): """ Add new field 'item' which is a link to TARGET_MODEL """ target_field = models.ForeignKey( cls.TARGET_MODEL, verbose_name=_(cls.TARGET_VERBOSE_NAME)) target_field.contribute_to_class(cls, 'item') status_field = models.CharField( max_length=30, choices=Item.STATUS_CHOICES + cls.STATUS_CHOICES, default=cls.DEFAULT_CHOICE, verbose_name=_('status')) status_field.contribute_to_class(cls, 'status') def __str__(self): return '%s: %s - %s' % (self.date.strftime('%Y-%m-%d'), self.status, self.item) class Meta: abstract = True ordering = ('-date', )