Django ORM FieldError в запросе некоторого расчета - PullRequest
1 голос
/ 06 мая 2020

Это моя модель для покупки:

class Purchase(models.Model):
    amount = models.DecimalField(
        max_digits=6,
        decimal_places=2,
        default=0.00
    )
    entry_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        related_name='ledger_entry_by',
    )

, а это моя модель потребления:

class Consume(models.Model):
    amount = models.FloatField(default=1)
    consumed_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        related_name='consume_entry_for',
    )

Я пытаюсь выяснить пользователя, который на сколько потребил больше, чем он покупок и кто сколько потребил меньше, чем он покупает

это мой запрос для этого:

purchase_vs_consume = User.objects.annotate(
            purchase_vs_consume=Coalesce(Sum('ledger_entry_for__amount'), Value(0))  - Coalesce(Sum('consume_entry_for__amount'), Value(0))
        )

Выдает следующую ошибку:

Expression contains mixed types: DecimalField, FloatField. You must set output_field

позже мой запрос был it:

purchase_vs_consume = User.objects.annotate(
            purchase_vs_consume=Coalesce(Sum('ledger_entry_for__amount'), Value(0))  - Coalesce(Sum('consume_entry_for__amount'), Value(0)), output_field=FloatField()
        )

выдает следующую ошибку:

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

Я не понимаю, что с этим не так.

Я хочу:

например, пользователь приобрел 500 долларов США, а он израсходовал 550 долларов США, то есть ему нужно заплатить еще 50 долларов США

другой пользователь купил 440 Долларов США, но он израсходовал 400 долларов США, то есть вы получите возмещение в размере 40 долларов США.

Другой пример пользователя: пользователь ничего не покупал, но он потратил 300 долларов США, поэтому он должен заплатить 300 долларов США

Я пытаюсь достичь выше этого расчета, но это вызывает у меня ошибку.

Может кто-нибудь он Как мне добиться этого?

1 Ответ

1 голос
/ 06 мая 2020
User.objects.annotate(purchase_vs_consume=Coalesce(Sum('ledger_entry_by__amount'), Value(0), output_field=FloatField()) - Coalesce(Sum('consume_entry_for__amount'), Value(0), output_field=FloatField())).values('purchase_vs_consume')

Обновите свой запрос. Вы используете два разных типа поля в каждой модели и выполняете вычисления. Таким образом, пока вы выполняете агрегирование внутри, вы должны передать output_field, чтобы вычисления происходили с теми же типами данных. Нет необходимости передавать output_field в случае consumer_entry_for, запрос будет работать без этого, поскольку поле уже является FloatField.

...