I'm trying to filter some products and order the filtered products by price ascending and descending.
This is my code in the view:
def is_valid_queryparam(param):
return param != '' and param is not None
def filter(request):
if request.GET:
price_min = request.GET.get('priceMin')
price_max = request.GET.get('priceMax')
sort_by = request.GET.get("sort", "l2h")
if is_valid_queryparam(price_min):
if sort_by == "l2h":
products = Product.objects.filter(price__gte=price_min).order_by('price')
elif sort_by == "h2l":
products = Product.objects.filter(price__gte=price_min).order_by('-price')
paginator = Paginator(products, 9)
page = request.GET.get('page')
paged_products = paginator.get_page(page)
product_count = products.count()
if is_valid_queryparam(price_max):
if sort_by == "l2h":
products = Product.objects.filter(price__lte=price_max).order_by('price')
elif sort_by == "h2l":
products = Product.objects.filter(price__lte=price_max).order_by('-price')
paginator = Paginator(products, 9)
page = request.GET.get('page')
paged_products = paginator.get_page(page)
product_count = products.count()
else:
products = Product.objects.all().order_by('price')
paginator = Paginator(products, 9)
page = request.GET.get('page')
paged_products = paginator.get_page(page)
product_count = products.count()
context={
'products': paged_products,
'product_count': product_count,
}
return render(request, 'store.html', context)
If I try to filter based on the min and max price it works, but when I'm trying to sort or if there is no filter apply I get this UnboundLocalError:
UnboundLocalError at /store/
local variable 'paged_products' referenced before assignment
Request Method: GET
Request URL: http://127.0.0.1:8000/store/?sort=h2l
Django Version: 3.1
Exception Type: UnboundLocalError
Exception Value:
local variable 'paged_products' referenced before assignment
Exception Location: C:\Users\store\views.py, line 299, in filter
I researched Django documentation, google and SO but I did not find a solution.
I have tried to rearrange the code, declare the variables as global, exclude 'sort' from the request.GET
params, and no success.
CodePudding user response:
You are getting UnboundLocalError
error because you have not defined an else
block for if is_valid_queryparam(price_min):
and if is_valid_queryparam(price_max):
as well as for sort by. As a result when you don't apply a filter paged_products
and product_count
never gets defined and raising UnboundLocalError at /store/ local variable 'paged_products' referenced before assignment
.
Try the following code below that will eliminate the issue as well as will optimize the code.
def is_valid_queryparam(param):
return param != '' and param is not None
def filter(request):
if request.GET:
price_min = request.GET.get('priceMin')
price_max = request.GET.get('priceMax')
sort_by = request.GET.get("sort", "l2h")
if is_valid_queryparam(price_min):
if sort_by == "l2h":
products = Product.objects.filter(price__gte=price_min).order_by('price')
elif sort_by == "h2l":
products = Product.objects.filter(price__gte=price_min).order_by('-price')
else:
products = Product.objects.filter(price__gte=price_min)
else:
products = Product.objects.all().order_by('price')
if is_valid_queryparam(price_max):
if sort_by == "l2h":
products = Product.objects.filter(price__lte=price_max).order_by('price')
elif sort_by == "h2l":
products = Product.objects.filter(price__lte=price_max).order_by('-price')
else:
products = Product.objects.filter(price__lte=price_max)
else:
products = Product.objects.all().order_by('price')
else:
products = Product.objects.all().order_by('price')
paginator = Paginator(products, 9)
page = request.GET.get('page')
paged_products = paginator.get_page(page)
product_count = products.count()
context = {
'products': paged_products,
'product_count': product_count,
}
return render(request, 'store.html', context)
CodePudding user response:
I slightly changed Nahidur Rahman's code in order for the minimum price filter to work, it is necessary to take the query from the minimum price and apply the filter for the maximum price.
def is_valid_queryparam(param):
return param != '' and param is not None
def filter(request):
if request.GET:
price_min = request.GET.get('priceMin')
price_max = request.GET.get('priceMax')
sort_by = request.GET.get("sort", "l2h")
if is_valid_queryparam(price_min):
if sort_by == "l2h":
products = Product.objects.filter(price__gte=price_min).order_by('price')
elif sort_by == "h2l":
products = Product.objects.filter(price__gte=price_min).order_by('-price')
else:
products = Product.objects.filter(price__gte=price_min)
else:
products = Product.objects.all().order_by('price')
if is_valid_queryparam(price_max):
if sort_by == "l2h":
products = products.filter(price__lte=price_max).order_by('price')
elif sort_by == "h2l":
products = products.filter(price__lte=price_max).order_by('-price')
else:
products = products.filter(price__lte=price_max)
else:
products = products
else:
products = Product.objects.all().order_by('price')
paginator = Paginator(products, 9)
page = request.GET.get('page')
paged_products = paginator.get_page(page)
product_count = products.count()
context = {
'products': paged_products,
'product_count': product_count,
}
return render(request, 'store.html', context)