Reputation: 1531
I am trying to filter my products list by price specified by user(min and max price).I have two input box for taking price range.'price' is one of the column in my database table.I am getting error as int() argument must be a string or a number, not 'dict'.I have include my template file and small part of views file.
Models.py,
class Add_prod(models.Model):
book = models.CharField("Book Name",max_length=40)
author = models.CharField("Author",max_length=30)
price = models.PositiveIntegerField("Price")
image = models.ImageField(upload_to='images',null=True)
cat = models.ForeignKey(Add_cat,on_delete=models.PROTECT)
def __unicode__(self):
return "%s" % (self.cat)
My template file,
<p>Price</p>
<input type="text" name="min_price" maxlength="4" size="3" >
to <input type="text" name="max_price" maxlength="4" size="3">
<input type="submit" value="Go">
views.py,
@csrf_protect
def welcome_user(request):
if 'min_price' in request.GET:
filter_price1 = request.GET.get('min_price')
filter_price2 = request.GET.get('max_price')
if filter_price1 =='':
filter_price1=0
if filter_price2=='':
filter_price2=Add_prod.objects.all().aggregate(Max('price'))
my_products = Add_prod.objects.filter(price__range=(filter_price1,filter_price2))
context = { "products":my_products}
return render(request,"welcome-user.html",context)
I also tried like this,
my_products = Add_prod.objects.raw('SELECT * FROM books_add_prod where price between filter_price1 and filter_price2')
Upvotes: 3
Views: 8337
Reputation: 73
Here is what worked for me, this might not be the optimal way to do it. But it works so anyone from future could give it a try:
<form method="get">
<input type="text" name="min_price" maxlength="4" size="3" required>
to <input type="text" name="max_price" maxlength="4" size="3" required>
<input type="submit" value="Go">
</form>
And In your Views:
if 'min_price' in request.GET:
filter_price1 = request.GET.get('min_price')
filter_price2 = request.GET.get('max_price')
if filter_price1 =='':
filter_price1=0
products = Products.objects.filter(price__range=(filter_price1,filter_price2))
Upvotes: 1
Reputation: 73460
Use aggregation (cheatsheet) as follows to determine the maximum price
:
from decimal import Decimal as D
...
price1 = D(request.GET.get('min_price', 0))
price2 = D(request.GET.get('max_price', 0))
if not price2:
price2 = Add_prod.objects.aggregate(Max('price'))['price__max']
my_products = Add_prod.objects.filter(price__range=(price1, price2))
On a different note, why do you use text
inputs for price
which I assume is a DecimalField
? What about a number input (or a django form) in order to make sure that the casts in your view don't raise errors :
<input type="number" name="min_price" min="0" step="0.01" >
Upvotes: 0
Reputation: 138
Maybe this line wrong filter_price2=Add_prod.objects.all().aggregate(Max('price'))
Cause aggragate will return a dict
See this docs Aggragation
Try this:
my_products=Add_prod.objects.filter(price__range(filter_price1,filter_price2['price_max']))
Upvotes: 2