Возможно ли иметь гибкие decimal_places для модели в django?

Я работаю в модели, которую я хотел бы использовать для различных видов инвестиций. Поэтому мне интересно, возможно ли иметь гибкие десятичные дроби.

Например:

Это класс

class Asset(models.Model):
    portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE, default=1)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    shares_amount = models.DecimalField(max_digits=18, decimal_places=0, default=0) 

Если я оставляю его пустым, то получаю ошибку: "DecimalFields должны определить атрибут 'decimal_places'."

Возможно, то, что я пытаюсь сделать, невозможно, возможно, мне нужно найти другое решение. Я открыт для предложений

Я хотел бы узнать, возможно ли сделать так, чтобы десятичные знаки можно было переставлять. Что-то вроде:

shares_amount = models.DecimalField(max_digits=18, decimal_places=x) 

if category == cryptocurrency
  x=18
else 
  x=0

Не уверен, что возможно достичь того, что вы описали, используя одно поле. Django отображает структуру модели на соответствующую таблицу в базе данных, и точная реализация хранения там может отличаться в зависимости от типа базы данных, которую вы используете. При этом shares_amount тип поля останется постоянным и может быть изменен только в процессе миграции. https://docs.djangoproject.com/en/4.0/ref/models/fields/#decimalfield

В качестве альтернативы можно подумать об использовании несколько иного подхода к хранению информации. Например, иметь два нулевых поля и заполнять их для каждого типа категории с правильной валидацией в зависимости от типа. Или иметь одно поле с максимально возможным количеством знаков после запятой и округлять их до нужной точности там, где это требуется.

Я нашел решение, которое работает для того, чего я хотел достичь.

Я изменил тип поля на FloatField, вместо DecimalField. Так я получил больше гибкости в отношении количества десятичных дробей, без ограничений:

shares_amount = models.FloatField() 

После использования некоторых математических операций, начал выдавать ошибку конфликта:

* неподдерживаемый тип(ы) операнда для : 'float' и 'decimal.Decimal'

Решение было найдено здесь на форуме:

неподдерживаемый тип(ы) операнда для *: 'float' и 'Decimal'

Так что для математики было просто сделать вот так:

decimal.Decimal(self.shares_amount) * self.share_cost


Вернуться на верх