Multiplying an integer and a decimal in a Django model using model expressions

663 Views Asked by At

I am a Django beginner and in one of my projects, I made this model:

class Piece(models.Model):
    
    order = models.ForeignKey(Order,on_delete=models.CASCADE)
    coil = models.ForeignKey(Cut_Material ,on_delete=models.CASCADE)
    piece_length = models.DecimalField(max_digits=4, decimal_places=2)
    prime_pieces = models.IntegerField()
    reject_pieces = models.IntegerField()

    def __str__(self):
        return (str(self.piece_length))

    class Meta:
        ordering = ["-order","piece_length"]

I want to multiply piece_length with prime_pieces to get running meters and here are my solutions:

Solution 1:

Solution: Piece.objects.annotate(running_meters = (F('piece_length') * F('prime_pieces')))

Error:TypeError: QuerySet.aggregate() received non-expression(s): <django.db.models.fields.FloatField>.

Solution 2

Solution: Piece.objects.annotate(running_meters = (F('piece_length') * F('prime_pieces')), output_field=FloatField())

Error: TypeError: QuerySet.aggregate() received non-expression(s): <django.db.models.fields.FloatField>.

Can anyone help me with a solution, please?

1

There are 1 best solutions below

0
On

By uising:

Piece.objects.annotate(
    running_meters = (F('piece_length') * F('prime_pieces')),
    output_field=FloatField()
)

(formatting added), you simply try to make an extra annotation output_field which maps to a FloatField.

What you need here is an ExpressionWrapper [Django-doc], and output_field=… is a parameter of ExpressionWrapper:

from django.db.models import ExpressionWrapper

Piece.objects.annotate(
    running_meters=ExpressionWrapper(
        F('piece_length') * F('prime_pieces'),
        output_field=FloatField()
    )
)