I have a function that returns a queryset and an html file with the results,
def get_queryset(self): # new
query = self.request.GET.get('q')
sort = '-date'
post_list = Post.objects.filter(
Q(title__icontains=query) #| Q(title__icontains=query) another field
).order_by(sort)
return post_list
form:
<form action="{% url 'search_results' %}" method="get">
<input name="q" type="text" placeholder="חפש מאמרים">
<button type="submit">חפש</button>
</form>
In the template for the results I want there to be a couple of links to sort by date, votes etc...
CodePudding user response:
You can write a little get form that adds the relevant order by a query param named order.
?order_by=-date
?order_by=score
?order_by=author
and get these in the view with request.GET.get("order_by")
or you can use a library like:
https://django-filter.readthedocs.io/en/stable/ref/filters.html
CodePudding user response:
Please don't allow arbitrary sorting: this is a security vulnerability since users can sort for example on the gender of the author of a Post
, which might be data you want to protect. You should work with a list of acceptable choices, so:
def get_queryset(self):
query = self.request.GET.get('q')
sort = self.request.GET.get('order_by', '-date')
if sort not in ['date', '-date', 'votes', '-votes']:
sort = '-date'
return Post.objects.filter(
Q(title__icontains=query) | Q(title__icontains=query)
).order_by(sort)
The url then should look like:
<a href="{% url 'search' %}?q={{ query|urlencode }}&order_by=-votes">votes</a>
with 'search'
the name of the path that points to this view.
Note: It might be worth to take a look at
django-filter
[GitHub] to do filtering based on aQueryDict
in a more declarative way.