class Lead(models.Model): # basic lead gen stuff goes here class Step(Default): lead = models.ForeignKey(Lead) active = models.BooleanField(default=False) comment = models.TextField(blank=True) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): getattr(self.lead, self.__class__.__name__.lower() + '_set').update(active=False) self.active = True super().save(force_insert, force_update, using, update_fields) def __str__(self): return self.name class Meta: abstract = True class InternalStage(Step): AVAILABLE_INTERNAL_STAGES = ( ('pending', 'Pending'), ('internally_approved', 'Internally Approved'), ('open', 'Open'), ) name = models.CharField(max_length=64, choices=AVAILABLE_INTERNAL_STAGES) class LeadQuerySet(models.query.QuerySet): def without_stage_of(self, stage, *names): """ Exclude stage(s). :param stage: str :param names: str :return: QuerySet """ stage = stage.replace('_', '') f = Q(**{stage + '__active': True}) for name in names: f = f & ~Q(**{stage + '__name': name}) return self.filter(f)