0

我有一个简单的对象过滤器,它使用price__ltprice__gt。这适用于我的产品模型上的一个名为 price 的属性,它是一个CharField[string](十进制看到相同的错误,并导致聚合出现问题,因此恢复为字符串)。

似乎在将这些值传递给过滤器时,它们被以一种奇怪的方式处理,例如 10 被视为 100。例如:

/products/price/10-200/ 退货价格为 100-200 的产品。过滤器作为 filterargs: 传入 FILTER ARGS: {'price__lt': '200', 'price__gt': '10'}。这也打破了 price/0-170 不会返回价格为 18.50 的产品的意义;出于某种原因,它将 170 视为“小于 18”。

知道什么会导致这种情况,以及如何解决它?谢谢!

4

1 回答 1

2

正如 Jeff 所建议的那样,问题在于价格是 a CharField,因此使用逐个字符串的比较逻辑进行比较,即任何以 开头的任何长度的字符串1都将小于任何以开头的任何长度的字符串,依此类推2

我很好奇您将 price 设置为 a 时遇到了什么问题IntegerField,因为这似乎是一个简单的解决方案,但是如果您需要将 price 保持为 a CharField,这是一种使查询工作的(hacky)方法:

lt = 200
gt = 10
qs = Product.objects.extra(select={'int_price': 'cast(price as int)'},
                           where=['int_price < %s', 'int_price > %s'],
                           params=[lt, gt])
qs.all()  # the result

这使用了Django 的 QuerySet 类的方法,您可以在此处extra的文档中阅读该方法。简而言之,它使用 SQL表达式计算字符串价格的整数版本,然后基于该表达式使用整数进行过滤。cast

于 2012-08-07T13:20:13.240 回答