Kiran
Kiran

Reputation: 1531

How to filter price range for products in django?

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

Answers (3)

Atit Bimali
Atit Bimali

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

user2390182
user2390182

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

Related Questions