A normalized schema, constraints in the database, and an index for the frequent lookup "price of product X for customer Y today".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # ====================================================================== # Q: Design the schema for B2B price lists (a different price per customer, with # validity dates). # # A normalized schema, constraints in the database, and an index for the # frequent lookup "price of product X for customer Y today". To prevent # overlapping periods: the PostgreSQL exclusion constraint with daterange # (ExclusionConstraint in django.contrib.postgres). The price charged is stored # in OrderItem, because the price list changes. # ====================================================================== class PriceList(models.Model): name = models.CharField(max_length=100) class PriceListEntry(models.Model): price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) price = models.DecimalField(max_digits=10, decimal_places=2) valid_from = models.DateField() valid_to = models.DateField(null=True, blank=True) class Meta: indexes = [models.Index(fields=['price_list', 'product', '-valid_from'])] constraints = [models.CheckConstraint( condition=Q(valid_to__isnull=True) | Q(valid_to__gte=F('valid_from')), name='pricelist_valid_range')] class Customer(models.Model): price_list = models.ForeignKey(PriceList, null=True, on_delete=models.SET_NULL) |