Джанго и конвертация единиц

Мне нужно сохранить некоторые значения в базе данных, расстояние, вес и т. Д. В моей модели у меня есть поле, которое содержит количество чего-то и параметр выбора IntegerField с выбором, который определяет, что означает это количество (длина, продолжительность и т. Д.). Должен ли я создать модель для единиц и физических величин или я должен использовать IntegerField, который содержит тип единицы?

3 ответа

Решение

Под "field(enum)" вы подразумеваете, что используете опцию выбора для поля?

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

Создание формальной модели для единиц должно быть выполнено только в том случае, если у вас есть (а) МНОГИЕ задействованные единицы, (б) ваша потребность расширять ее, И (в) есть некоторые рациональные ожидания, что поиск в БД будет иметь какую-то ценность.

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

Выбор

Например, вы можете использовать что-то подобное, чтобы отслеживать конверсии.

UNIT_CHOICES = ( ('m', 'meters'), ('f', 'feet' ), ('i', 'inches'), ('pt', 'points') )

unit_conversions = {
    ('m','f'): 3.xyz,
    ('m','i'): 39.xyz,
    ('m','pt'): 29.xyz*72,
    ('f','m'): 1/3.xyz,
    ('f','i'): 12.0,
    ('f','pt'): 12.0*72,
    etc.
}

Учитывая это отображение, вы можете получить коэффициент преобразования в функции метода преобразования, выполнить математические вычисления и вернуть преобразованные единицы измерения.

class WithUnit( Model ):
    ...
    def toUnit( self, someUnit ):
        if someUnit == self.unit: return self.value
        elif (someUnit,self.unit) in unit_conversions:
            return self.value * unit_conversions[(someUnit,self.unit)]
        else:
            raise Exception( "Can't convert" )

Модель

Если вы хотите создать формальную модель для единиц, вы должны учитывать тип измерения (длина, объем, масса, вес / сила, давление, температура и т. Д.) И различные коэффициенты пересчета единиц. Это работает для всего, кроме температуры, где у вас есть постоянный член в дополнение к фактору.

Вы должны выбрать базовый набор единиц (например, MKS) и нести все множители между различными единицами.

Вы также должны выбрать, сколько английских единиц нужно загрузить в ваш стол (жидкие унции, чайные ложки, столовые ложки, чашки, пинты, кварты и т. Д.)

Используйте поле, которое указывает тип меры (вес, длина и т. Д.), И сохраните значение в другом поле. Этого должно быть достаточно. Единица измерения должна быть неявной. Я предполагаю, что вы используете одну и ту же единицу измерения для каждого типа измерения, например, всегда метры для длины.

Конкретный пример: допустим, у вас есть две сущности, "Car" и "CarMeasures". Я бы написал модель так:

class Car(models.Model):
    type=models.CharField(max_length=256);

class CarMeasures(models.Model):
    carId=models.ForeignKey(Car);
    measureValue=models.DecimalField(..., max_digits=10, decimal_places=2);
    measureType=models.CharField(max_length=32);

Это зависит от того, как вы хотите его использовать. Допустим, у вас есть значение длины и две возможные единицы, см и мм. Если вы хотите напечатать значение позже, вы всегда можете распечатать его как единицу измерения.

Однако, если вы хотите выполнить некоторые вычисления со значением, например, вычислить площадь, вам необходимо преобразовать значения в те же единицы. Так что вы все равно должны определить таблицу перевода единиц.

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

Я бы добавил модель для единиц и физических величин только в том случае, если их слишком много и конверсия действительно сложна. Такая модель может работать как конвертер. Но для простых случаев, таких как mm⇒cm или inch⇒cm, достаточно статической таблицы преобразования.

Другие вопросы по тегам