有条件地更改字段值以在Dj​​ango ORM中进行查找

时间:2018-11-19 19:16:22

标签: python django django-orm

我正在尝试在查找过程中有条件地更改字段值-我想到了一些特定的顺序,我不想覆盖字段值,而只是按照自己的方式对其进行排序。假设我有一个类Product,每个类对象都有product_code字段。现在我想获得小于或等于的值,但这并不无关紧要-product_code在大多数情况下都是类似A01B02等,以及Django查找lte会工作。但是现在我有一个字段0001C01,我想成为最大的价值。因此,在查找期间,我想在每个没有此前缀的字符串的开头添加0000,因此看起来像0001C010000B020000A01。 / p>

2 个答案:

答案 0 :(得分:1)

这听起来很简单。提取所需的Product对象,如果每个对象都不以该字符串开头,则将0000放在product_code之前。

products = Product.objects.filter(some_query_expression)
for product in products:
    if not product.product_code.startswith('0000'):
        product.product_code = '0000' + product.product_code

尚不清楚是要将此值保存回数据库,还是仅用于临时比较。如果要保存,请致电product.save()

答案 1 :(得分:1)

您可以有条件地注释您的查询集,以获取具有所需值的新字段,然后在filterorder_by子句中使用此字段。例如,您可以执行以下操作:

from django.db.models import CharField, Value as V, F, Q, Case, When
from django.db.models.functions import Concat

Product.objects.annotate(
    new_product_code=Case(
        When(product_code__iregex=r'^[A-Z]+.*',  # If it starts with letters  
             then=Concat(V('0000'), 'product_code', output_field=CharField())  # Then prepend four 0's
        ), 
        default=F('product_code')  # Else, the original value
    )
).filter(new_product_code__lte='whatever you like')  # Now filter by using your new value

文档的相关部分是conditional expressionsdatabase functionsQuerySet API reference