【问题标题】:Can I django filter a CharField by range?我可以 django 按范围过滤 CharField 吗?
【发布时间】:2015-11-20 21:15:30
【问题描述】:

如何过滤所有产品的 5 到 15 之间的价格?

我有这个模型:

class Product(models.Model):
    price = models.CharField(max_length=150, default= 12)

我试过了

Products.objects.all().filter(price__range=(5, 15))

但我没有得到任何东西。

你知道怎么做吗?

【问题讨论】:

  • 你为什么要使用 CharField,尤其是如果你想用数字过滤它?为什么不是整数域或小数域?

标签: python django django-queryset


【解决方案1】:

Django 可以按范围过滤 CharField 吗?

大概吧。 __range 字段查找作为BETWEEN 查询直接通过数据库推送。由于字符串是有序的(即服从排序规则),BETWEEN 适用于 char 字段。

...但我没有得到任何对象

因为515 被转换为char 字段的字符串。在我知道'5' > '15' 的每个字符串集合中,因此该范围内不能有任何值。

正如@Daniel-Roseman 所建议的,如果您想要进行数值比较,请使用正确的numeric field,该范围将按预期工作。

【讨论】:

  • 更改为数字字段解决了所有问题。感谢您的快速回答!
【解决方案2】:

使用 Cast 函数将 price 字段的结果转换为整数,然后进行范围过滤

https://docs.djangoproject.com/en/4.0/ref/models/database-functions/#cast

from django.db.models import IntegerField
from django.db.models.functions import Cast

Products.objects.annotate(price_as_int=Cast('price',IntegerField()).filter(price_as_int__range=(5,15))

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案3】:

对于那些在 Google 上找到这个问题并希望在 CharField 上实际实现 RangeFilter 的人,这也是可能的,但默认情况下不会。首先在你的过滤器之前创建这个类:

from django import forms
from django_filters import rest_framework as filters, fields

class CharRangeFilter(filters.RangeFilter):
    class CharRangeField(fields.RangeField):
        def __init__(self, *args, **kwargs):
            super().__init__(fields=(
                forms.CharField(),
                forms.CharField()
            ), *args, **kwargs)
        field_class = CharRangeField

然后在您的过滤器中使用它,例如:

class MyFilter(filters.FilterSet):
    my_char_field = CharRangeFilter()

    class Meta:
        model = MyModel
        fields = ['my_char_field']

之所以创建自己的RangeField类是因为RangeFilter动态创建了一个RangeField,它默认使用两个DecimalField对象,并且默认不能从RangeFilter对象更改,因为@ 987654328@ 仅通过field_class 知道RangeField

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-26
    • 2022-08-14
    • 2020-03-09
    • 2014-09-04
    • 2017-08-05
    • 1970-01-01
    • 2014-06-14
    • 2015-05-12
    相关资源
    最近更新 更多