Reputation: 65
I'm using ListView in my Class Based Views and I want to sort the goods by the selected field by the user, but I couldn't find the information I needed
view
class Shop(ListView):
template_name = 'essense/shop.html'
context_object_name = 'items'
paginate_by = 9
allow_empty = False
def get_queryset(self):
return Item.objects.all()
def get_context_data(self, *, object_list=None, **kwargs):
***context***
return context
def get_ordering(self):
ordering = self.request.GET.get('orderby',)
print(ordering)
return ordering
template
<form action="{% url 'shop' %}" method="get" id="sortProduct">
<div class="product-sorting d-flex">
<p>Sort by:</p>
<select type="submit" name="select">
<option type="submit" name="orderby" value="price">Price: $$ - $</option>
<option type="submit" name="orderby" value="-price">Price: $ - $$</option>
</select>
<input type="submit" class="d-none" value="">
</div>
</form>
Upvotes: 1
Views: 75
Reputation: 476594
You should not override the get_queryset
, since there is where the ordering logic is happening. You can specify the model with the model
attribute [Django-doc]:
class Shop(ListView):
model = Item
template_name = 'essense/shop.html'
context_object_name = 'items'
paginate_by = 9
allow_empty = False
# no get_queryset
def get_ordering(self):
return self.request.GET.get('orderby',)
or if you want to filter the queryset by making a super call:
class Shop(ListView):
model = Item
template_name = 'essense/shop.html'
context_object_name = 'items'
paginate_by = 9
allow_empty = False
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).all()
def get_ordering(self):
return self.request.GET.get('orderby',)
Note that it is not very safe to let a user select an arbitrary order by. Hashed passwords can be retrieved if one for example orders on user__password
for example. Usually it is better to retain a list of fields that are allowed to order by.
Upvotes: 1