Django аннотирует с помощью

Как я могу использовать переменные average_ndvi и field_count в annotate, мне нужно изменить 0.14 на F "average_ndvi", 5 на F "field_count".

 commune = (
        Commune.objects.annotate(
            year=SearchVector("field__fieldattribute__date__year"),
            month=SearchVector(Cast("field__fieldattribute__date__month", CharField())),
            size=Sum(F("field__fieldattribute__planted_area")),
            average_ndvi=Avg(F("field__fieldattribute__ndvi")),
            field_count=Count("field"),
            standart_deviation=Sum(
                ((F("field__fieldattribute__ndvi") - 0.14) ** 2) / 5,
                output_field=FloatField(),
            ),
        )
        .filter(year=year, month=str(month))
        .only("id", "name")
    )

Вы просто помещаете standart_deviation в отдельный, второй вызов annotate. Там вы сможете ссылаться на поля, добавленные первым вызовом annotate:

 commune = (
        Commune.objects.annotate(
            year=SearchVector("field__fieldattribute__date__year"),
            month=SearchVector(Cast("field__fieldattribute__date__month", CharField())),
            size=Sum(F("field__fieldattribute__planted_area")),
            average_ndvi=Avg(F("field__fieldattribute__ndvi")),
            field_count=Count("field"),
        ).annotate(
            standart_deviation=Sum(
                ((F("field__fieldattribute__ndvi") - F("average_ndvi")) ** 2) / F("field_count"),
                output_field=FloatField(),
            ),
        )
        .filter(year=year, month=str(month))
        .only("id", "name")
    )

Вы можете заменить 0.14 на Avg(F("field__fieldattribute__ndvi")) и 5 на Count("field"), потому что доступ к агрегированным значениям осуществляется по условию HAVING. Я думаю, что это будет работать.

commune = (
        Commune.objects.annotate(
            year=SearchVector("field__fieldattribute__date__year"),
            month=SearchVector(Cast("field__fieldattribute__date__month", CharField())),
            size=Sum(F("field__fieldattribute__planted_area")),
            average_ndvi=Avg(F("field__fieldattribute__ndvi")),
            field_count=Count("field"),
            standart_deviation=Sum(
                ((F("field__fieldattribute__ndvi") - Avg(F("field__fieldattribute__ndvi"))) ** 2) / Count("field"),
                output_field=FloatField(),
            ),
        )
        .filter(year=year, month=str(month))
        .only("id", "name")
    )
Вернуться на верх