2012-03-28 5 views
3

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

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 мин»}
  • {"group": "A", "amount": "2 min"}
  • {"group": "B", "amount": "20 min" }
  • {"group": "B", "amount": "1 hr"}

они в конечном итоге отсортированный что-то вроде этого:

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

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

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

ответ

0

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

E.g. «02 мин.»

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

+0

Это не вариант. Во-первых, я использую строковое представление объекта [quantity] (http://packages.python.org/quantities/user/tutorial.html), и мне не нужно будет редактировать этот код. И даже если бы я это сделал, было бы неизвестное число ведущих нулей. Я использую его для хранения не только времени, но и всего. Например, может быть 10000 фунтов. – RotaJota

1

Я думаю, что нет способа отсортировать его как числа. Я имею в виду не эффективный способ, так как я считаю, что 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

В этом случае возможно ли создать собственное хранилище полей django в базе данных как два столбца (один столбец для суммы, один для единицы)? Даже тогда я хотел бы иметь возможность сравнить объект python, так как это не позволило бы сравнивать разные единицы (например, минуты и час). – RotaJota

+0

Существует [билет] (https: //code.djangoproject. com/ticket/5929) о полях с несколькими столбцами. В качестве обходного пути вы можете сериализовать количественный объект, используя модуль [pickle] (http://docs.python.org/library/pickle.html). И это не очень удобно, но вам нужно выбрать одну единицу измерения для одного ресурса (время, вес и т. Д.), Если вы хотите эффективную сортировку. – Kirill

+1

Интересно, не делаете ли вы излишне тяжело на себя. Я понимаю, что вы предпочитаете сортировать Python, но для этого требуется сначала загрузить все из базы данных в память, а затем сделать вид. Я также настоятельно рекомендую не хранить в базе данных разные единицы одного типа (время, расстояние, вес), проще всего хранить все, например. минут и работать с этим. – knabar

0

Я пойду с совершенно другим подходом.

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

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

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

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

Смежные вопросы