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}'
Вернуться на верх