Django ORM将两列相加以填充第三列

时间:2015-01-08 19:15:33

标签: python django sqlite sorting django-tables2

让我们说,我有一个像这样的SQLite表:

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

我这样做是因为我在项目中添加了一个django-tables2表,我想自定义我的表格,但就我搜索而言,没有办法做到这一点。我只能按A列或B列对表进行排序。但它按字母顺序对它们进行排序,我的值不同。

另一种可能性是使用SQL查询对我的表进行排序,如下所示:

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

但是我必须在django中使用raw方法来做到这一点,对吧?用ORM插入是不可能的?至少这是我迄今为止所理解的。或者我只是不知道该怎么做。 :P

所以我没有使用raw,而是认为添加第三列只是为了按顺序对整个表进行排序;)

嗯,事实证明并不像我希望的那么简单,如果可能的话我想得到任何帮助。 谢谢!

1 个答案:

答案 0 :(得分:2)

这是一种方法。不建议命名modelfield field_afield_sum,但优于asum

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            

关于覆盖save()方法的Django文档: 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()