РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
164 of 818 menu

Класс ExpressionWrapper

Класс ExpressionWrapper применяется для обёртки выражений (например, F-выражений или агрегаций) с явным указанием типа выходных данных. Это особенно важно, когда выражение используется в условиях фильтрации или сортировки, и Django не может автоматически определить тип результата. В качестве основного аргумента передаётся выражение, а параметр output_field определяет тип поля результата.

Синтаксис

from django.db.models import ExpressionWrapper, F from django.db.models import IntegerField ExpressionWrapper(F('field') + 1, output_field=IntegerField())

Пример . Модель

Рассмотрим модель Product с полями price и discount:

from django.db import models class Product(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) discount = models.IntegerField(default=0) # percent def __str__(self): return self.name

Пример . С вычислением цены

Вычислим итоговую цену с учётом скидки для всех товаров:

from django.db.models import ExpressionWrapper, F, DecimalField from myapp.models import Product # Calculate final price with discount products = Product.objects.annotate( final_price=ExpressionWrapper( F('price') * (1 - F('discount') / 100.0), output_field=DecimalField(max_digits=10, decimal_places=2) ) ) for product in products: print(f"{product.name}: {product.final_price}")

Результат выполнения кода:

"Laptop: 850.50" "Phone: 560.00" "Tablet: 320.00"

Пример . С условием фильтрации

Используем ExpressionWrapper для фильтрации товаров, у которых итоговая цена меньше заданного значения:

from django.db.models import ExpressionWrapper, F, DecimalField, Q from myapp.models import Product # Filter products where final price < 500 discounted_products = Product.objects.filter( ExpressionWrapper( F('price') * (1 - F('discount') / 100.0), output_field=DecimalField(max_digits=10, decimal_places=2) ) < 500 ) for product in discounted_products: print(f"{product.name}: {product.price}")

Результат выполнения кода:

"Phone: 700.00" "Tablet: 400.00"

Пример . С использованием в сортировке

Отсортируем товары по итоговой цене с учётом скидки:

from django.db.models import ExpressionWrapper, F, DecimalField from myapp.models import Product # Order by final price products = Product.objects.annotate( final_price=ExpressionWrapper( F('price') * (1 - F('discount') / 100.0), output_field=DecimalField(max_digits=10, decimal_places=2) ) ).order_by('final_price') for product in products: print(f"{product.name}: {product.final_price}")

Результат выполнения кода:

"Tablet: 320.00" "Phone: 560.00" "Laptop: 850.50"

Пример . С агрегацией

Вычислим среднюю итоговую цену товаров с использованием агрегации:

from django.db.models import ExpressionWrapper, F, DecimalField, Avg from myapp.models import Product # Calculate average final price avg_price = Product.objects.aggregate( avg_final=Avg( ExpressionWrapper( F('price') * (1 - F('discount') / 100.0), output_field=DecimalField(max_digits=10, decimal_places=2) ) ) ) print(avg_price['avg_final'])

Результат выполнения кода:

"576.83"

Смотрите также

  • класс F,
    который позволяет выполнять операции на уровне базы данных
  • класс Q,
    который используется для создания сложных условий фильтрации
  • класс Case,
    который реализует условные выражения в запросах
  • класс Value,
    который используется для обёртки значений в выражения
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить