Reputation: 1781
I have a search form with id, price_from, price_to and drive_from, driven_too, but since price and driven are the same logic I am only focusing in one of these, since price_from and price_to are not in the model, it gives me an error because this parameter does not exist, therefore it can not compare anything.
How can i search in the car objects for an object which price is within this range (price_from - price_to), should i modify my model?
# model
class Car(models.Model):
id = models.CharField(max_length=255)
number = models.CharField(max_length=255)
price = models.IntegerField()
# view
def search(request):
if 'search_filter' in request.GET:
search_params = request.GET.dict()
search_params.pop("search_filter")
price_from = search_params['price_from']
price_to = search_params['price_to']
q_list = [Q(("{}__icontains".format(param), search_params[param])) for param in search_params
if search_params[param] is not None]
my_query = Car.objects.filter(reduce(operator.and_, q_list))
cars = [{
'id': x.id,
'driven': x.driven,
'price': x.price,
} for x in my_query
]
return JsonResponse({'data': cars})
context = {'cars': Car.objects.all().order_by('price')}
return render(request, 'cars/car_index.html', context)
Upvotes: 2
Views: 2274
Reputation: 476594
You can construct a Q(..)
object with:
Q(price__gte=price_from, price__lte=price_to)
or you can exclude the bounds with:
Q(price__gt=price_from, price__lt=price_to)
although it is possible that price_from
or price_to
is None
, and thus construct a Q
object with kwargs:
if 'search_filter' in request.GET:
search_params = request.GET.dict()
search_params.pop('search_filter')
price_from = search_params.pop('price_from', None)
price_to = search_params.pop('price_to', None)
q_list = [
Q(('{}__icontains'.format(k), v))
for k, v in search_params.items()
if v is not None
]
price = { 'price__gte': price_from, 'price__lte': price_to }
q_list.append(Q(**{k: int(v) for k, v in price.items() if v is not None}))
# ...
Upvotes: 3