有条件地更改字段值以在 Django ORM 中查找
Conditionally change field value for lookup in Django ORM
我正在尝试在查找期间有条件地更改字段值 - 我有一些特定的顺序,我不想覆盖字段值,只是按照我的方式对其进行排序。比方说,我有 classProduct
并且每个 class 对象都有 product_code
字段。现在我想得到小于或等于,但这不是微不足道的 - product_code
大多数时候都是这样的 A01
,B02
等等和 Django 查找 lte
会工作。但现在我有字段 0001C01
,我希望它成为最大的值。所以在查找过程中,我想在每个没有这个前缀的字符串的开头添加 0000
,所以它看起来像 0001C01
、0000B02
、0000A01
.
这听起来很简单。获取所需的 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()
.
您可以有条件地注释您的查询集以获得具有所需值的新字段,然后在您的 filter
或 order_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 expressions, database functions and QuerySet API reference
我正在尝试在查找期间有条件地更改字段值 - 我有一些特定的顺序,我不想覆盖字段值,只是按照我的方式对其进行排序。比方说,我有 classProduct
并且每个 class 对象都有 product_code
字段。现在我想得到小于或等于,但这不是微不足道的 - product_code
大多数时候都是这样的 A01
,B02
等等和 Django 查找 lte
会工作。但现在我有字段 0001C01
,我希望它成为最大的值。所以在查找过程中,我想在每个没有这个前缀的字符串的开头添加 0000
,所以它看起来像 0001C01
、0000B02
、0000A01
.
这听起来很简单。获取所需的 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()
.
您可以有条件地注释您的查询集以获得具有所需值的新字段,然后在您的 filter
或 order_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 expressions, database functions and QuerySet API reference