【问题标题】:Django - Iterate over queryset and add static valuesDjango - 遍历查询集并添加静态值
【发布时间】:2017-06-14 14:21:36
【问题描述】:

在以下查询集中,我按员工过滤每周计划的小时数(displayval 是我在此查询集中的一周)。当员工在我过滤的一周内没有计划小时数时,我想添加一个计划小时数 = 0 的项目。

实现这一目标的最简单方法是什么?

def DesignHubR(request):
        emp3_list = Projectsummaryplannedhours.objects.values_list('displayval', 'employeename')
                .filter(businessunit='a')
                .filter(billinggroup__startswith='PLS - Project')
                .filter(Q(displayval=sunday2)|Q(displayval=sunday))
                .annotate(plannedhours__sum=Sum('plannedhours'))
        emp3 = map(lambda x: {'date': x[0], 'employee_name': x[1], 'planned_hours': x[2]}, emp3_list)
        context = {'sunday': sunday, 'sunday2': sunday2, 'emp3': emp3}
        return render(request,'department_hub_ple.html', context)

【问题讨论】:

    标签: python django


    【解决方案1】:

    我认为您可以使用Coalesce(*expressions, **extra) 函数来解决您的问题。

    接受至少两个字段名称或表达式的列表并返回第一个非空值(注意空字符串不被视为空值)。

    所以您的查询将如下所示:

    from django.db.models import Sum, Value
    from django.db.models.functions import Coalesce
    emp3_list = \
        Projectsummaryplannedhours.objects.\
                filter(
                    Q(businessunit='a') &
                    Q(billinggroup__startswith='PLS - Project') &
                    (Q(displayval=sunday2) | Q(displayval=sunday))
                ).\
                annotate(plannedhours__sum=Coalesce(
                            Sum('plannedhours'), Value(0)
                        )
                ).\
                values_list('displayval', 'employeename')
    

    更多信息请参见https://docs.djangoproject.com/en/1.9/ref/models/database-functions/#coalesce

    如果不存在要求和的条目,这将帮助您获得plannedhours__sum = 0。如果您还想在plannedhours__sum = 0 所在的每个条目中添加其他参数,您可以使用 Django 条件表达式。有关更多信息,请阅读 Case 表达式 (https://docs.djangoproject.com/en/1.11/ref/models/conditional-expressions/#case)。

    Case() 接受任意数量的 When() 对象作为单独的参数。其他选项使用关键字参数提供。如果没有任何条件评估为 TRUE,则返回使用默认关键字参数给出的表达式。如果未提供默认参数,则使用 None。

    from django.db.models import Sum, Value, IntegerField
    from django.db.models.functions import Coalesce
    emp3_list = \
        Projectsummaryplannedhours.objects.\
            filter(
                Q(businessunit='a') &
                Q(billinggroup__startswith='PLS - Project') &
                (Q(displayval=sunday2) | Q(displayval=sunday))
            ).\
            annotate(plannedhours__sum=Coalesce(
                        Sum('plannedhours'), Value(0)
                    ),
                    x=Case(When(plannedhours__sum=0, then=Value(0)),
                    output_field=IntegerField())
            ).\
            values_list('displayval', 'employeename')
    

    如果计划小时数 = 0 而其他地方没有,这将为您提供额外的参数 x 等于 0。您还可以通过注释值过滤emp3_list

    因此,您可以将查询集传递给模板context = {'sunday': sunday, 'sunday2': sunday2, 'emp3': emp3_list},在那里对其进行迭代并获取您需要的属性:

    for q in emp3_list:
        print(q[0], q[1], q[2])
    

    希望对你有所帮助。

    【讨论】:

    • 感谢您的回复。我的planned_hours 是一个十进制字段,所以我使用了它,我得到了这个错误:“DecimalField 的不支持查找'sum'或不允许加入该字段。”
    • 如果您尝试将 IntegerField() 更改为 DecimalField() 并将 Sum('plannedhours') 更改为 Sum(F('palannedhours')) 怎么办?
    • 无论我使用 output_field=IntegerField() 还是 output_field=DecimalField(),我都会遇到同样的错误
    • 这很奇怪。我正在尝试在 DecimalField 上注释 Sum() 并且它可以正常工作。我的示例是 decimal_sum = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=2) 作为模型字段,Event.objects.annotate(a__sum=Coalesce(Sum('decimal_sum'), Value(0))).values_list('id') 作为查询。
    • 在其他查询中,我使用聚合和合并。在这个查询中,我已经用注释求和了。
    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    相关资源
    最近更新 更多