Django ORM求和两列以填充第三列
Django ORM to sum two columns to fill a third one
比方说,我有一个 SQLite table 这样的:
A | B | SUM
-------------
AA | BA |
AB | BB |
AC | BC |
现在我想为它们设置数值,以填充第三列。
例如:
AA = 1 BA = 1
AB = 3 BB = 3
AC = 2 BC = 2
所以数据库中的 table 应该是这样的:
A | B | SUM
-------------
AA | BA | 2
AB | BB | 6
AC | BC | 4
我这样做是因为,我在我的项目中添加了一个 django-tables2 table,我想自定义排序我的 table,但就我搜索了一下,没有办法做到这一点。我只能按 A 列或 B 列对 table 进行排序。但它按字母顺序对它们进行排序,而我的值不同。
另一种可能性是使用 SQL 查询对我的 table 进行排序,如下所示:
ORDER BY CASE WHEN A = 'AA' THEN 1
WHEN A = 'AB' THEN 3
WHEN A = 'AC' THEN 2 END
但是我必须在 django 中使用 raw 方法才能做到这一点,对吗?用 ORM 插入它是不可能的?至少到目前为止我是这么理解的。或者我只是不知道该怎么做。 :P
所以我认为添加第三列而不是使用 raw 会很简单,只是为了按那个排序整个 table ;)
好吧,结果并没有我希望的那么简单,如果可能的话,我想得到任何帮助。
谢谢!
这是一种方法。不建议将模型字段命名为 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
关于覆盖 save() 方法的 Django 文档:
https://docs.djangoproject.com/en/1.7/topics/db/models/#overriding-predefined-model-methods
您可能想阅读一些有关数据库设计和规范化的内容。将派生值存储在数据库中通常不是一个好主意。
如果您在不使用 Django ORM 和 save() 方法的情况下更改 VALUES 字典或更新 table,field_sum 中的值可能是错误的。
保存所有实例将确保 field_sum 正确。
for instance in Example.objects.all(): instance.save()
比方说,我有一个 SQLite table 这样的:
A | B | SUM
-------------
AA | BA |
AB | BB |
AC | BC |
现在我想为它们设置数值,以填充第三列。 例如:
AA = 1 BA = 1
AB = 3 BB = 3
AC = 2 BC = 2
所以数据库中的 table 应该是这样的:
A | B | SUM
-------------
AA | BA | 2
AB | BB | 6
AC | BC | 4
我这样做是因为,我在我的项目中添加了一个 django-tables2 table,我想自定义排序我的 table,但就我搜索了一下,没有办法做到这一点。我只能按 A 列或 B 列对 table 进行排序。但它按字母顺序对它们进行排序,而我的值不同。
另一种可能性是使用 SQL 查询对我的 table 进行排序,如下所示:
ORDER BY CASE WHEN A = 'AA' THEN 1
WHEN A = 'AB' THEN 3
WHEN A = 'AC' THEN 2 END
但是我必须在 django 中使用 raw 方法才能做到这一点,对吗?用 ORM 插入它是不可能的?至少到目前为止我是这么理解的。或者我只是不知道该怎么做。 :P
所以我认为添加第三列而不是使用 raw 会很简单,只是为了按那个排序整个 table ;)
好吧,结果并没有我希望的那么简单,如果可能的话,我想得到任何帮助。 谢谢!
这是一种方法。不建议将模型字段命名为 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
关于覆盖 save() 方法的 Django 文档: https://docs.djangoproject.com/en/1.7/topics/db/models/#overriding-predefined-model-methods
您可能想阅读一些有关数据库设计和规范化的内容。将派生值存储在数据库中通常不是一个好主意。
如果您在不使用 Django ORM 和 save() 方法的情况下更改 VALUES 字典或更新 table,field_sum 中的值可能是错误的。
保存所有实例将确保 field_sum 正确。
for instance in Example.objects.all(): instance.save()