简体   繁体   English

如何在 Django 中进行条件查询?

[英]How to make a conditional query in Django?

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我正在尝试按sales_price (计算字段)过滤,其中sales_price的定义如下伪代码

if discount is NULL                                                             
    sales_price = price                                                         
else                                                                            
    sales_price = price - price*discount/100 

The end goal is to filter sales_price by range:最终目标是按范围过滤sales_price

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)                                                                             

I'll just point you in the right direction:我只会指出你正确的方向:

Use F expressions in a conditional expression with When and Case在带有WhenCase的条件表达式中使用F表达式

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)您想按依赖于其他值的值进行排序,因此让我们在条件表达式中使用F 表达式(因为sales_price依赖于其他字段)(因为最终表达式取决于discount是否为NULL

First we construct a sales_price value that depends on discount and price , and annotate our query with it:首先,我们构造一个依赖于discountpricesales_price值,并用它来注释我们的查询:

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:现在,您已经包含了一个sales_price ,您可以使用它进行过滤:

   Product.objects.annotate(...).filter(sales_price__range=(price_min, price_max)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM