Home > Back-end >  Sort search results in django
Sort search results in django

Time:04-11

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 }}&amp;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 a QueryDict in a more declarative way.

  • Related