Должен ли я использовать `FloatField()` или `DecimalField(`) от Django для длины звука?

Я использую:

duration = float(ffmpeg.probe(audio_path)["format"]["duration"])

Я собираю длину аудио/видео и хочу хранить ее с помощью своих моделей. Следует ли мне использовать models.DecimalField() или models.FloatField()?

Я использую его для расчета и хранения кредита/затрат в моей модели, используя

credit = models.DecimalField(max_digits=20, decimal_places=4)

При хранении значения длительности, особенно если оно связано с вычислениями, такими как подсчет кредитов или затрат, в Django обычно лучше использовать DecimalField. Это связано с тем, что DecimalField позволяет явно контролировать точность и масштаб (количество знаков после запятой), гарантируя, что вы не столкнетесь с ошибками округления, которые могут возникнуть при использовании арифметики с плавающей точкой.

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

Согласованность: Если вы уже используете DecimalField для кредитного поля, то использование этого поля в течение всего срока гарантирует, что ваши расчеты, включающие оба поля, будут последовательными и точными.

Пример кода.

from django.db import models

class YourModel(models.Model):
    duration = models.DecimalField(max_digits=10, decimal_places=4)
    credit = models.DecimalField(max_digits=20, decimal_places=4)
  • max_digits=10: Определяет общее количество цифр, которые может содержать поле, включая цифры до и после десятичной точки.
  • decimal_places=4: Определяет, сколько цифр может быть сохранено после десятичной точки.

Я думаю, что самый разумный способ - использовать DurationField model поле [Django-doc]. Django посмотрит, какую базу данных использует бэкенд, и попытается работать с наиболее сенситивным типом столбцов, который предлагает база данных:

class MyModel(models.Model):
    duration = models.DurationField()

и работать с:

from datetime import timedelta

MyModel.objects.create(
    duration=timedelta(
        seconds=float(ffmpeg.probe(audio_path)['format']['duration'])
    )
)
Вернуться на верх