2015-01-08 1 views
2

Позволяет сказать, у меня есть таблица SQLite вроде этого:Django ORM суммировать два столбца, чтобы заполнить третий один

A | B | SUM 
------------- 
AA | BA | 
AB | BB | 
AC | BC | 

и теперь я хотел бы задать числовые значения для них, чтобы заполнить третий колонка. Например:

AA = 1 BA = 1 
AB = 3 BB = 3 
AC = 2 BC = 2 

Так таблица в базе данных будет выглядеть так:

A | B | SUM 
------------- 
AA | BA | 2 
AB | BB | 6 
AC | BC | 4 

Я делаю это потому, что я добавил таблицу Джанго-tables2 для моего проекта, и я хотел бы для индивидуальной сортировки моей таблицы, но, насколько я искал, нет способа сделать это. Я могу сортировать таблицу только по столбцам A или B. Но он упорядочивает их в алфавитном порядке, а мои значения разные.

Другая возможность заключается в использовании SQL запроса для сортировки моего стола, как это:

ORDER BY CASE WHEN A = 'AA' THEN 1 
       WHEN A = 'AB' THEN 3 
       WHEN A = 'AC' THEN 2 END 

Но я должен был бы использовать необработанный метод в Джанго, чтобы сделать это, не так ли? Вставить его в ORM невозможно? По крайней мере, это то, что я понял до сих пор. Или я просто не знаю, как это сделать. : P

Таким образом, вместо того, чтобы использовать сырье, я думал, что это было бы просто добавить третью колонку только заказать всю таблицу на что;)

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

+0

Что вы хотите сказать? Вы можете рассчитать значение в третьем столбце в методе save() модели. –

+0

Я настоящий нуб, так что, пожалуйста, дайте мне пример. Я должен написать код в файл models.py? Fe. У меня есть класс Example (models.Model), с 3 столбцами: A, B и SUM. Как указать, что я хочу, чтобы AA равнялся 2 и AB равным 3 и т. Д.? – Jagulari

+0

Я разместил предложение. Было бы легче ответить, если бы вы включили код модели в вопрос. –

ответ

1

Это один из способов сделать это. Называть modelfields field_a или field_sum не рекомендуется, но лучше, чем просто a или sum.

from django.db import models 


class Example(models.Model): 
    VALUES = { 
     'AA': 1, 
     'AB': 3, 
     'AC': 2, 
     'BA': 1, 
     'BB': 3, 
     'BC': 2, 
    } 

    field_a = models.CharField(default='AA', max_length=2,) 
    field_b = models.CharField(default='BA', max_length=2,) 

    # The value in this field is derived from the first two. 
    # Updated every time the model instance is saved. 
    field_sum = models.PositiveIntegerField(
     default=0, # This value will be overwritten during save() 
     editable=False, # Hides this field in the admin interface. 
    ) 

    def save(self, *args, **kwargs): 
     # calculate sum before saving. 
     self.field_sum = self.calculate_sum() 
     super(Example, self).save(*args, **kwargs) 

    def calculate_sum(self): 
     """ Calculate a numeric value for the model instance. """ 
     try: 
      value_a = self.VALUES[self.field_a] 
      value_b = self.VALUES[self.field_b] 
      return value_a + value_b 
     except KeyError: 
      # Value_a or value_b is not in the VALUES dictionary. 
      # Do something to handle this exception. 
      # Just returning the value 0 will avoid crashes, but could 
      # also hide some underlying problem with your data. 
      return 0    

Джанго документация о переопределении методы сохранения(): https://docs.djangoproject.com/en/1.7/topics/db/models/#overriding-predefined-model-methods

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

Если вы изменили словарь VALUES или обновили таблицу без использования метода Django ORM и метода save(), значение в поле field_sum может быть неправильным.

Сохранение всех экземпляров гарантирует, что поле field_sum верное.

for instance in Example.objects.all(): instance.save() 
+0

Да! Спасибо! Вот что я имел в виду! Извините за то, что вы не предоставили пример модели, но хорошо импровизировали! P.S - немного опечатка в def save. Должно быть self.calculate_sum(). ;) – Jagulari

+0

Я немного изменил пример кода. Я не тестировал его, поэтому могут быть некоторые опечатки. –