Возможно ли иметь гибкие 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