【问题标题】:Django ORM to sum two columns to fill a third oneDjango ORM 将两列相加以填充第三列
【发布时间】:2015-01-08 19:15:33
【问题描述】:

可以说,我有一个这样的 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 会很简单;)

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

【问题讨论】:

  • 您的问题是什么?可以在模型的save()方法中计算第三列的值。
  • 我是一个真正的菜鸟,所以请你举个例子。我应该将代码写入models.py文件吗?费。我有一个类 Example(models.Model),有 3 列:A、B 和 SUM。如何指定我希望 AA 等于 2 和 AB 等于 3 等?
  • 我已经发布了一个建议。如果您在问题中包含您的模型代码,会更容易回答。

标签: python django sqlite sorting django-tables2


【解决方案1】:

这是一种方法。不建议将模型字段命名为 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()

【讨论】:

  • 是的!谢谢!这就是我的意思!很抱歉没有提供一个典型的例子,但你的即兴发挥很好! P.S - def 保存中的一个小错字。应该是 self.calculate_sum()。 ;)
  • 我稍微更改了示例代码。我没有测试过,所以可能还有一些错别字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
相关资源
最近更新 更多