Выборочная сортировка по настраиваемому полю в Django - PullRequest
3 голосов
/ 28 марта 2012

В моем приложении я определил настраиваемое поле для представления физической величины с использованием пакета Количества .

class AmountField(models.CharField):
    def __init__(self, *args, **kwargs):
        ...

    def to_python(self, value):
        create_quantities_value(value)

По сути, он работает так, как будто он расширяет CharField для хранения значения в виде строки в базе данных

"12 min"

и представляет его как объект количеств при использовании поля в модели

array(12) * min

Тогда в модели оно используется так:

class MyModel(models.Model):
    group = models.CharField()
    amount = AmountField()

    class Meta:
        ordering = ['group', 'amount']

Моя проблема в том, что эти поля сортируются не по количеству, а по строке.

Так что, если у меня есть объекты, которые содержат что-то вроде

  • {"группа": "А", "сумма": "12 мин"}
  • {"группа": "А", "сумма": "20 мин"}
  • {"группа": "А", "сумма": "2 мин"}
  • {"группа": "B", "сумма": "20 минут"}
  • {"группа": "B", "количество": "1 час"}

в итоге они сортируются примерно так:

>>> MyModel.objects.all()
[{A, 12 min}, {A, 2 min}, {A, 20 min}, {B, 1 hr}, {B, 20 min}]

по существу в алфавитном порядке.

Могу ли я дать своему пользовательскому AmountField функцию сравнения, чтобы он сравнивался по значению python вместо значения DB?

Ответы [ 3 ]

1 голос
/ 28 марта 2012

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

class MyModel(models.Model):
    group = models.CharField()
    amount = models.IntegerField()  # or PositiveIntegerField

    class Meta:
        ordering = ['group', 'amount']

    def amountAsQuantityObject(self):
        return create_quantities_value(self.amount)

    # or as a property
    quantity_object = property(amountAsQuantityObject)
0 голосов
/ 28 марта 2012

Я собираюсь пойти с совершенно другим подходом.

Вместо того, чтобы иметь собственное поле для хранения единиц времени, почему бы не сохранить единицы времени?

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

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

Это будет иметь другие преимущества. Допустим, вы хотели добавить все эти единицы времени, как это было раньше. Для этого потребуется некоторая обработка строки и замена этой части строки на то, что имеет add или sub или аналогичные методы.

0 голосов
/ 28 марта 2012

Не могли бы вы сохранить его с ведущими нулями в базе данных?

например. "02 мин"

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

...