'Can I django filter a CharField by range?
How can I filter the prices between 5 and 15 for all the products?
I have this model:
class Product(models.Model):
price = models.CharField(max_length=150, default= 12)
I tried
Products.objects.all().filter(price__range=(5, 15))
but I get no objects.
Any idea on how to do this?
Solution 1:[1]
Use Cast function and convert the result of price field to integer and then do a range filter
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))
Solution 2:[2]
For those finding this question on Google looking to actually implement a RangeFilter on a CharField, this is also possible but not by default. First create this class before your filter:
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
And then use it in your filter, like this for example:
class MyFilter(filters.FilterSet):
my_char_field = CharRangeFilter()
class Meta:
model = MyModel
fields = ['my_char_field']
The reason creating your own RangeField class is because RangeFilter dynamically creates a RangeField, which by default uses two DecimalField objects, and the default can't be changed from the RangeFilter object because RangeFilter is only aware of RangeField via field_class.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Brian Nieves |
