Как суммировать значение для указанного поля c - PullRequest
0 голосов
/ 24 апреля 2020

У меня следующая ситуация

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)

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Вы можете аннотировать Sottocategoria объекты суммой quantita:

from django.db.models import Sum

Sottocategoria.objects.annotate(
    <b>quantita=Sum('meteriale__quantita')</b>
)

Sottocategoria объектов, которые возникают из этого набора запросов, будет иметь дополнительный атрибут .quantita, который содержит сумму quantita связанных Materiale объектов.

Таким образом, вы можете использовать этот запрос в представлениях, где вам нужно всего quantita, а затем, например, отобразить его в шаблоны с {{ mysottocategoria.quantita }}.

Если вам это нужно часто, вы можете использовать manager для этого:

class <b>SottocategoriaManager</b>(models.Manager):

    def get_queryset(self):
        super().get_queryset().annotate(
            <b>quantita=Sum('meteriale__quantita')</b>
        )

class Sottocategoria(models.Model):
    # &hellip;

    <b>objects = SottocategoriaManager()</b>

Теперь каждый раз, когда вы получаете доступ к Sottocategoria.objects Таким образом, он вернет аннотированный набор запросов.

Можно использовать выражение Coalesce [Django -doc] для замены NULL на 0 если нет связанных meteriale:

from django.db.models import Sum, Value
from django.db.models.functions import Coalesce

Sottocategoria.objects.annotate(
    <b>quantita=Coalesce(Sum('meteriale__quantita'), Value(0))</b>
)

Вы можете реализовать это в менеджере, если вам нужно часто, как указано ранее.

0 голосов
/ 25 апреля 2020

На мой взгляд, я добавляю этот код:

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. Еще вопросы: можно ли заменить результат «Нет» на ноль?

Спасибо

...