I am trying to filter by a calculated field, where the calculation depends on the value of other fields.
I'm trying to filter by sales_price (the calculated field), where sales_price is defined like below pseudocode
if discount is NULL
sales_price = price
else
sales_price = price - price*discount/100
The end goal is to filter sales_price by range:
filter(sales_price__range=(price_min, price_max))
Here is my model:
class Product(models.Model):
price = models.IntegerField()
discount = models.IntegerField(blank=True, null=True)
¶ Django allows using SQL subqueries.
Definition of the all() manager method: all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result.
A QuerySet is a collection of data from a database. A QuerySet is built up as a list of objects. QuerySets makes it easier to get the data you actually need, by allowing you to filter and order the data.
I'll just point you in the right direction:
F expressions in a conditional expression with When and Case
You want to sort by a value that depends on other values, so let's use a F Expression (because sales_price depends on other fields) in a conditional expression (because the final expression depends on whether discount is NULL or not)
First we construct a sales_price value that depends on discount and price, and annotate our query with it:
from django.db.models import When, Case, F, IntegerField
Product.objects.annotate(
sales_price=Case(
When(discount__isnull=True, then=F('price')),
When(discount__isnull=False, then=(F('price') - (F('discount') * F('price')) / 100)),
output_field=IntegerField(),
)
)
Now with this, you have included a sales_price that you can filter with:
Product.objects.annotate(...).filter(sales_price__range=(price_min, price_max)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With