使用Django ORM值并调用成员函数

时间:2018-07-11 12:08:09

标签: django django-orm

我的Django应用中具有以下模型。

class Revenue(models.Model):
    from_a = models.IntegerField()
    from_b = models.IntegerField()

    def get_total(self):
        return self.from_a + self.from_b

现在我正在使用Revenue.objects.filter(from_a__gt = 10).values('from_a', 'from_b')检索数据。

从上面的查询集中,我正在获取值,现在我想在对象上调用get_total函数。 我没有找到调用该函数的方法。

有没有一种方法可以只使用values检索我需要的数据,并且还可以调用该对象的member_functions

如果我的模型有100列,则

Revenue.objects.filter(from_a__gt = 10)应该不是解决方案。

3 个答案:

答案 0 :(得分:1)

您可以在查询中使用F expression来代替模型级的操作:

from django.db.models import F

Revenue.objects.filter(from_a__gt = 10).annotate(
    get_total=F('from_a') + F('from_b')
).values('from_a', 'from_b', 'get_total')

答案 1 :(得分:1)

  

从上面的查询集中,我正在获取值,现在我想在对象上调用get_total函数。我没有找到调用该函数的方法。

好吧,您获得了QuerySet(当时尚未评估),因此有Revenue s的集合。您不能直接在该集合上调用该函数。但是您可以通过查询集 iterate ,并在单个对象上调用该函数。例如,我们可以使用以下列表:

[r.get_total() for r in Revenue.objects.filter(from_a__gt = 10)]
  

有没有一种方法可以只使用值来检索我需要的数据,还可以调用该对象的member_functions

是的,您可以在查询中使用.only(..)元素来限制要加载的列数:

[r.get_total() for r in Revenue.objects.filter(from_a__gt = 10).only('from_a', 'from_b')]

这将构造Revenue对象,但我们只会加载指定的列。在这种情况下,我们将仅加载from_afrom_b,如果以后需要 other 字段,则会使用 extra 查询加载这些字段。 / p>

如果member_function中的逻辑很简单,则最好使用注释:然后在数据库中对其进行处理,从而允许进行过滤。但是,这并非总是可能的:Python允许计算非常复杂的事情,这将导致巨大的等效SQL表达式。此外,大多数数据库不允许联系Web服务和文件系统,因此某些功能从根本上讲是无法翻译为注释的。

答案 2 :(得分:0)

取决于您要执行的操作...如果您希望get_total显示为字段,则可以将此方法作为一种propetry方法,他将被计算为字段,因此它不会保留在数据库中

属性方法

@property
def get_total(self):
    return self.from_a + self.from_b

Revenue.objects.filter(from_a__gt = 10).values('from_a', 'from_b', 'get_total')

https://docs.djangoproject.com/en/2.0/topics/db/models/#model-methods

您可以像常规类方法一样调用它,因此,在获取模型实例时可以调用它

revenues = Revenue.objects.filter(from_a__gt = 10).values('from_a', 'from_b')
for revenue in revenues:
    print(revenue.get_total())

# OR
[r.get_total() for r in Revenue.objects.filter(from_a__gt = 10)] # Like Wilem Van said

或将其用作静态方法(这种方法不是最适合您的需求,但很高兴知道),您会将这种方法与类绑定,因此您不需要一个对象实例来管理它,只需类参考即可     收入类别(...):         ...

    @staticmethod
    def get_total(valueA, valueB):
        return valueA + valueB

这样称呼它     Revenue.get_total(5,10)

https://www.programiz.com/python-programming/methods/built-in/staticmethod

不好意思:很奇怪,在Django文档中没有对static方法有很好的了解