Skip to content

Instantly share code, notes, and snippets.

@singingwolfboy
Last active October 19, 2016 20:47
Show Gist options
  • Save singingwolfboy/6f3301a8cccb1b81d9119b98914fcebe to your computer and use it in GitHub Desktop.
Save singingwolfboy/6f3301a8cccb1b81d9119b98914fcebe to your computer and use it in GitHub Desktop.
An example of how we might implement tiers that can be modified over time without losing the old information
class Tier(models.Model):
program = models.ForeignKey(Program)
name = models.TextField()
description = models.TextField()
@property
def current_version(self):
return self.tier_versions.order_by('-active_at').first()
@property
def discount_amount(self):
return self.current_version.discount_amount
@property
def income_threshold(self):
return self.current_version.income_threshold
class TierVersion(models.Model):
"""
An append-only data structure to update the financial details of a tier.
Every time a tier is "updated", we actually create a new TierVersion
object and associate it with the tier. This allows us to see the financial
details of tiers as they were in the past.
"""
tier = models.ForeignKey(Tier, related_name="tier_versions")
discount_amount = models.IntegerField(null=False)
income_threshold = models.IntegerField(null=False)
active_at = models.DateTimeField(auto_now=True)
class FinancialAid(models.Model):
user = models.ForeignKey(User)
tier = models.ForeignKey(Tier)
submitted_at = models.DateTimeField(auto_now=True)
@property
def tier_version(self):
return (
TierModification.objects
.filter(tier=self.tier)
.filter(active_at__lte=self.submitted_at)
.order_by('active_at')
.first()
)
@property
def discount_amount(self):
return self.tier_version.discount_amount
@property
def income_threshold(self):
returns self.tier_version.income_threshold
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment