简体   繁体   English

Django:如何将 **kwarg 传递给 annotate()

[英]Django: how to pass **kwarg to annotate()

I am new to django framework and Python.我是 django 框架和 Python 的新手。 I have a requirement do aggregation on the fields picked at runtime by the users我需要对用户在运行时选择的字段进行聚合

class Department(models.Model):
  code = models.CharField(max_length=10, primary_key=True)
  size = models.IntegerField(blank=True, null=True)
  budget = models.IntegerField(blank=True, null=True)

I would like to optionally do the sum of either size,budget or both using **kwarg by doing something like the following我想通过执行以下操作来选择使用 **kwarg 来计算大小、预算或两者的总和

from django.db.models import Avg, Count, Sum
# let Fname has the name of the field to sum on, set by a user input
FName='size' 
FList={}
# problem in passing the following
FList['total_size']="Sum(' "+FName+" ')" 
data=Department.objects.annotate(**FList)

But I receive the following error但我收到以下错误

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "c:\python34\lib\site-packages\django\db\models\query.py", line 802, in annotate
    is_summary=False)
  File "c:\python34\lib\site-packages\django\db\models\sql\query.py", line 1030, in add_aggregate
    field_list = aggregate.lookup.split(LOOKUP_SEP)
AttributeError: 'str' object has no attribute 'lookup'

implying from the discussion in the list that Sum is not recognized in the key, value pair从列表中的讨论暗示在键值对中无法识别 Sum

Any help in passing the **kwarg to annotate is appreciated感谢您通过 **kwarg 进行注释的任何帮助

You're passing the string "Sum(blah)", hence the error.您正在传递字符串“Sum(blah)”,因此出现错误。

FList['total_size'] = Sum(FName)

But really there's no reason to use kwargs here at all:但实际上根本没有理由在这里使用 kwargs:

data=Department.objects.annotate(total_size=Sum(FName))

Simplify..简化..

from django.db.models import Avg, Count, Sum
# let Fname has the name of the field to sum on, set by a user input
FName='size' 
data=Department.objects.annotate(total_size=Sum(FName))

Since FName is a string, you don;t need to wrap it with quotes.由于FName是一个字符串,因此您不需要用引号括起来。 If you needed tto run a different function, say avg etc...如果您需要运行不同的功能,例如 avg 等...

from django.db.models import Avg, Count, Sum
# let Fname has the name of the field to sum on, set by a user input
FName='size' 
function_t = Sum # or Avg, or Count
data=Department.objects.annotate(total_size=function_t(FName))

I hope this helps you get down the path我希望这可以帮助你走上这条路

For those who really wanted to pass a kwarg to annotate probably 'cause it is defined dinamically you have to do the following:对于那些真正想通过kwarg进行注释的人,可能因为它是动态定义的,你必须执行以下操作:

annotate_filters = {
    'sum_foo': Count('foo', distinct=True),
}
if foo:
    annotate_filters['sum_foo'] = Count('bar', distinct=True)
Foo.objects.annotate(**annotate_filters)

In this way you can manage different condition and pass them to the annotate function.通过这种方式,您可以管理不同的条件并将它们传递给注释函数。

Happy coding.快乐编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM