0

I have a model as a CharField but all values are int.

salary_amount_min = models.CharField(max_length=10, default='', null=True)
salary_amount_max = models.CharField(max_length=10, default='', null=True)

How to do a Filter to get Less Than Equal and Greater Than Equal on these fields?

My current filter:

search_salary_min = hr_form.cleaned_data['search_salary_min ']
search_salary_max = hr_form.cleaned_data['search_salary_max ']
salaryMinQS = Q(salary_amount_min__gte=search_salary_min )
salaryMaxQS = Q(salary_amount_max__lte=search_salary_max )

If I display on terminal the QS:

MIN (AND: ('salary_amount_min__gte', '2100000')) MAX (AND: ('salary_amount_max__lte', '2600000'))

rod james
  • 369
  • 3
  • 13
  • Why don't you migrate it to an `IntegerField`? You may need to write a data migration but it's the best solution. – Selcuk Feb 25 '21 at 04:12
  • I started this without prior knowledge on Django and when I started using IntegerField, there was this arrow on my input to increase/decrease the value. At that time I dont know how to remove it so I used CharField instead. If I change it now, it may affect a lot of things on my project. – rod james Feb 25 '21 at 04:14
  • I get it and it's your decision but I wouldn't leave such a technical debt that will come back and haunt you over and over down the road. – Selcuk Feb 25 '21 at 04:16
  • Noted on it. For now, I will try to change it. But any idea how to accomplish this? My current predicament. – rod james Feb 25 '21 at 04:18
  • Does this answer your question? [How do I parse a string to a float or int?](https://stackoverflow.com/questions/379906/how-do-i-parse-a-string-to-a-float-or-int) – Sumithran Feb 25 '21 at 04:23
  • the arrow is the default form field of integerfield, you can change it to different form field type – Linh Nguyen Feb 25 '21 at 04:33
  • I know how to parse to int. but the filter on fields is a string. unless you are referring to int(salary_amount_min__gte) which did not work. – rod james Feb 25 '21 at 04:35
  • if you want to use __gte i'm afraid you have to change it to integer/number field instead of string field, just make a migration for it – Linh Nguyen Feb 25 '21 at 04:40

2 Answers2

2

You can use the DB function Cast to cast a value to another datatype using an annotation and then filter on this annotation

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

MyModel.objects.annotate(
    salary_amount_min_int=Cast('salary_amount_min', output_field=IntegerField()),
    salary_amount_max_int=Cast('salary_amount_max', output_field=IntegerField())
).filter(
    salary_amount_min_int__gte=search_salary_min,
    salary_amount_max_int__lte=search_salary_max
)
Iain Shelvington
  • 31,030
  • 3
  • 31
  • 50
1

You can use a custom manager, its very inefficient

 from django.db import models

    class MyManager(models.Manager):
    
        def salary_gte(self, max):
            items = []
            for obj in self.all():
                if int(obj.search_salary_max) < max:
                    items.append(obj)
            return items
Jibin Mathews
  • 1,129
  • 1
  • 10
  • 23