Django - Создание модели с полями, производными от другой модели
У меня есть 2 модели Django, представляющие домен монет. Монета имеет некоторые свойства, а торговая пара основана на этих свойствах.
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')
Добавим пару экземпляров монет:
first = Coin.objects.create(code="BTC", name="Bitcoin")
second = Coin.objects.create(code="USD", name="United States Dollar")
и одна пара:
Pair.objects.create(code="BTCUSD", name="Bitcoin / United States Dollar", base_currency=first, quote_currency=second)
Как видите, код и имя в модели Pair могут быть получены из кода и имени в модели Coin. Проще говоря:
- Код пары = Код первой монеты + Код второй монеты
- Имя пары = Имя первой монеты + "/" + Имя второй монеты
Но в данном примере я просто жестко закодировал эти значения, и наверняка это не лучший способ справиться с данной ситуацией. Например, что если в модели Coin мне нужно будет изменить имя экземпляра? Тогда мне придется вручную обновить код и имя в модели Pair, потому что эти значения не привязаны должным образом к модели Coin.
Я считаю, что код/имя пары должен быть каким-то образом связан/выведен из модели монеты.
Есть ли способ сделать это в Django?
Возможно, вам не нужно хранить имя вашего Pair
, поскольку оно может быть выведено из ссылок Pair.base_currency
и Pair.quote_currency
.
Свойства на классе Pair
должно быть достаточно:
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}'