I have 2 Django models representing the coin domain. The Coin has some properties and the trading Pair is based on those properties.
class Coin(models.Model):
code = models.CharField(max_length=8, primary_key=True)
name = models.CharField(max_length=32)
class Pair(models.Model):
code = models.CharField(max_length=16, primary_key=True)
name = models.CharField(max_length=64)
base_currency = models.ForeignKey(Coin, on_delete=models.CASCADE, null=False, related_name='base_currency')
quote_currency = models.ForeignKey(Coin, on_delete=models.CASCADE, null=False, related_name='quote_currency')
Let's add a couple of Coin instances:
first = Coin.objects.create(code="BTC", name="Bitcoin")
second = Coin.objects.create(code="USD", name="United States Dollar")
and one Pair:
Pair.objects.create(code="BTCUSD", name="Bitcoin / United States Dollar", base_currency=first, quote_currency=second)
As you can see, code and name in the Pair model can be derived from code and name in the Coin model. To put it simple:
- Pair Code = First Coin Code Second Coin Code
- Pair Name = First Coin Name "/" Second Coin Name
But, in this example I simply hardcoded those values and for sure this is not the best way to handle this situation. For example: what if in the Coin model I need to change the name of an instance? Then, I will have to manually update code and name in the Pair model, because this values are not properly binded from the Coin Model.
I believe Pair code/name must be binded/derived from the Coin model in some way.
Is there a way to do that in Django?
CodePudding user response:
You might not need to store the name of your Pair
since it can be infered from the references from Pair.base_currency
and Pair.quote_currency
.
A property on the Pair
class should be enough:
class Pair(models.Model):
base_currency = models.ForeignKey(Coin, on_delete=models.CASCADE, null=False, related_name='base_currency')
quote_currency = models.ForeignKey(Coin, on_delete=models.CASCADE, null=False, related_name='quote_currency')
@property
def code(self) -> str:
return self.base_currency.code self.quote_currency.code
@property
def name(self) -> str:
return f'{self.base_currency.name} / {self.quote_currency.name}'