Как умножить и суммировать два столбца в разных таблицах в django

У меня есть приложение для расчета диет на основе питательных веществ каждого блюда. В админке этого приложения я хочу вывести цену каждого блюда в таблицу Meal, что мне удалось сделать, вычислив цену при отображении в админке:

# admin.py

class AdminMeal(admin.ModelAdmin):
    list_display = ['name', 'meal_type_names', 'price']

    @admin.display(description='Price')
    def price(self, obj):
        unit_prices = np.asarray(obj.mealingredient_set.order_by('id').values_list('ingredient__unit_price'))
        amounts = np.asarray(obj.mealingredient_set.order_by('id').values_list('amount'))
        to_return = float(np.matmul(np.transpose(unit_prices), amounts) / 1000)
        return mark_safe(to_return)

Теперь мой главный вопрос: Мне нужно позволить упорядочить таблицу Meal на основе Price, что я не знаю как сделать. На основе моих поисков кажется, что я должен использовать annotate вместо моего текущего способа вычисления цены, чтобы иметь возможность сортировать мою таблицу, я нашел решение в здесь

# admin.py

class AdminMeal(admin.ModelAdmin):
    list_display = ['name', 'meal_type_names', 'price']

    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        queryset = queryset.annotate(_price=Sum('mealingredient__amount * mealingredient__ingredient__unit_price'))

Но, к сожалению, он выдает эту ошибку (я думаю, это потому, что я пытаюсь SUM над разными таблицами): Unsupported lookup 'amount * mealingredient' for AutoField or join on the field not permitted. Любая помощь приветствуется, простите меня, если я упустил что-то очевидное, я новичок в django.

Некоторые из соответствующих Models для Meal таблицы:

# models.py

class Meal(models.Model):
    id = models.AutoField(primary_key=True)
    meal_type = models.ForeignKey(MealType, on_delete=models.CASCADE, null=True, blank=True, related_name='meal_type')
    meal_types = models.ManyToManyField(MealType, blank=True)
    name = models.CharField(max_length=255, null=True, blank=True)


class MealIngredient(models.Model):
    id = models.AutoField(primary_key=True)
    meal = models.ForeignKey(Meal, on_delete=models.CASCADE, null=True, blank=True)
    user_meal = models.ForeignKey(UserMeal, on_delete=models.CASCADE, null=True, blank=True)
    ingredient = models.ForeignKey(Ingredient, on_delete=models.SET_NULL, null=True, blank=True)
    amount = models.DecimalField(max_digits=14, decimal_places=4, default=0)


class Ingredient(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, null=True, blank=True)
    state = models.CharField(max_length=255, null=True, blank=True)
    unit_price = models.IntegerField(null=True, blank=True)

Вам необходимо использовать ExpressionWrapper:

    from django.db.models import DecimalField, ExpressionWrapper, F, Sum

    queryset = queryset.annotate(
        _price=Sum(
             ExpressionWrapper(
                  F('mealingredient__amount') * 
                  F('mealingredient__ingredient__unit_price'),
                  output_field=DecimalField()
             )
        )
    )
Вернуться на верх