How can I add a new field for each queryset in the Filter object?

How can I add the total_categories variable as a field for each product?
I want to use this field to sort products.

products = Product.objects.filter()

for item in products:

    total_categories = 0
    for cat in item.categories.all()
        sub_category = cat.sub_category
        main_category = cat.main_category
        total_categories = sub_category + main_category 


Thank you.

You need to perform that operation as part of a query expression and then annotate that value as a field in the queryset.

See the docs and examples at Aggregation | Django documentation | Django

Can you provide paid support on this issue? If I send you my real code. According to the information there, I could not achieve the result I wanted.

Sorry, no.

But if you post what you’ve tried on here, we can work it forward from what you have. It would also be helpful if you posted the smallest portion of the models necessary to create the solution. (We don’t need the entire models, just the fields involved.)

products = Product.objects.filter(
    ).annotate(total=( Sum('warehouseReceivedOf__received_amount', default=0) + Sum('warehouseReceivedOf__cart_amount', default=0) + Sum('warehouseReceivedOf__out_amount', default=0) + Sum('warehouseReceivedOf__shipped_amount', default=0) + Sum('warehouseReceivedOf__disposed_amount', default=0) ) 
    ).annotate(inbound=( Sum('warehouseReceivedOf__expected_amount', default=0) - F('total') )

    #I can achieve the result I want with python without the orm structure.
    #Frankly, I need to convert the python code here to ORM structure.
    #The value obtained as a result of the operation here gives me the inbound information.
    """ for item in products:
        total_diff = 0
        for received_qs in item.warehouseReceivedOf.all():
            item_expected = received_qs.expected_amount

            item_received =  received_qs.received_amount
            item_cart = received_qs.cart_amount
            item_out = received_qs.out_amount
            item_shipped = received_qs.shipped_amount
            item_dispose = received_qs.disposed_amount

            total = item_received + item_cart + item_out + item_shipped + item_dispose
            if item_expected > total:
                total_diff += item_expected - total
        item.inbound = total_diff """

#As I don't know how to use "if item_expected > total" in orm structure, I get a wrong result. As a result of the values satisfying the if condition, I can reach the inbound value.

You’re really close.

The “if” condition is handled by a conditional expression.

Your second annotate could then be something like:

.annotate(unit_diff = Case(
    When(item_expected__gt=F('total'), then=F('item_expected') - F('total')),

This is going to annotate each element with the diff for that element.

Then, depending upon what you need to do with the results, you can do an aggregate on unit_diff to calculate the total_diff.

1 Like

I changed the code you gave a bit and it solved my problem.
Thank you very much, KenWhitesell.