【问题标题】:How to sum value ​for a specific field如何对特定字段求和
【发布时间】:2020-08-08 11:39:38
【问题描述】:

我有以下情况

Sottocategoria | Quantità
type_1         |  100.00
type_2         |  100.00
type_1         |  100.00

我想获得一个新表,它给我以下视图:

Sottocategoria | Quantità
type_1         |  200.00
type_2         |  100.00

这里是我的 models.py 与“quantita”和“sottocategoria”字段的情况:

class Tipologia(models.Model):
    nome= models.CharField('Categoria', max_length=30)

class Sottocategoria(models.Model):
    tipologia = models.ForeignKey(Tipologia, on_delete=models.CASCADE)
    name = models.CharField( max_length=30)

class Materiale(models.Model):
    conto = models.CharField('Conto', max_length=30, choices=(
            ('MATERIA PRIMA', 'MATERIA PRIMA'),
            ('SUSSIDIARIA', 'SUSSIDIARIA'),
        ))
    tipologia = models.ForeignKey(Tipologia, on_delete=models.SET_NULL, null=True)
    sottocategoria = models.ForeignKey(Sottocategoria, on_delete=models.SET_NULL, null=True)
    quantita=models.DecimalField('Quantità',max_digits=5)

【问题讨论】:

    标签: django django-models django-rest-framework django-forms django-views


    【解决方案1】:

    您可以使用quantita 的总和来注释Sottocategoria 对象:

    from django.db.models import Sum
    
    Sottocategoria.objects.annotate(
        quantita=Sum('meteriale__quantita')
    )

    this 查询集产生的Sottocategoria 对象将具有一个额外的属性.quantita,其中包含相关Materiale 对象的quantita 的总和。

    因此,您可以在需要总数 quantita 的视图中使用此查询,然后在模板中使用 {{ mysottocategoria.quantita }} 渲染它。

    如果你经常需要这个,你可以使用 manager

    class SottocategoriaManager(models.Manager):
    
        def get_queryset(self):
            super().get_queryset().annotate(
                quantita=Sum('meteriale__quantita')
            )
    
    class Sottocategoria(models.Model):
        # …
    
        objects = SottocategoriaManager()

    现在每次访问Sottocategoria.objects,它都会返回一个带注释的查询集。

    如果没有相关的meteriale,可以使用Coalesce expression [Django-doc]NULL 替换为0

    from django.db.models import Sum, Value
    from django.db.models.functions import Coalesce
    
    Sottocategoria.objects.annotate(
        quantita=Coalesce(Sum('meteriale__quantita'), Value(0))
    )

    如果您需要经常按照之前指定的方式在管理器中实现此功能。

    【讨论】:

    • 非常感谢,但是我应该在哪里添加这段代码?在视图或模型中?因为这个值,我必须在我项目的其他视图和其他应用程序中使用它
    • 你很可能必须在所有单独的视图中这样称呼它
    • @FedericoDeMarco:在你需要的视图中,或者如果你经常需要,你可以写一个经理(见编辑)。
    【解决方案2】:

    在我看来,我添加了以下代码:

    def magazzino(request):
        elements = Materiale.objects.all()
    
        if request.method == 'POST':
             form = MaterialeForm(request.POST)
             if form.is_valid():
                 print("Il form è valido")
                 new_input = form.save()
    
        else :
            form = MaterialeForm()
            elements = Materiale.objects.all()
    
        agg=Sottocategoria.objects.annotate(quantita=Sum('materiale__quantita'))
    
        context= {
            "form": form,
            'elements':elements,
            'agg' : agg,
    
                }
        return render(request, "magazzino/magazzino.html", context)
    

    在我的模板中:

    {% for e in agg %}
              <tr>
                  <td> {{e.name}} </td>
                  <td> {{e.tipologia}} </td>
                  <td> {{e.quantita}} </td>
                  {% endfor %}
              </tr>
    

    正确吗?有效,但如果我的代码遵循 DRY 原则,我现在不可以。另一个问题:可以用零替换结果“无”吗?

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多