Сортировка результатов поиска в django

У меня есть функция, которая возвращает набор запросов и html-файл с результатами,

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 class="form-inline my-2 my-lg-0" action="{% url 'search_results' %}" method="get">
      <input class="form-control" name="q" type="text" placeholder="חפש מאמרים">
      <button class="btn btn-outline-success my-sm-0" type="submit">חפש</button>
    </form>

В шаблоне для результатов я хочу, чтобы было несколько ссылок для сортировки по дате, голосам и т.д...

Вы можете написать небольшую форму get, которая добавляет соответствующий порядок по параметру запроса с именем order.

?order_by=-date
?order_by=score
?order_by=author

и получить их в представлении с помощью request.GET.get("order_by")

или вы можете использовать библиотеку типа:

https://django-filter.readthedocs.io/en/stable/ref/filters.html

Пожалуйста, не разрешайте произвольную сортировку: это уязвимость безопасности, так как пользователи могут сортировать, например, по полу автора Post, что может быть данными, которые вы хотите защитить. Вы должны работать со списком допустимых вариантов, например:

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)

Тогда url должен выглядеть следующим образом:

<a href="{% url 'search' %}?q={{ query|urlencode }}&amp;order_by=-votes">votes</a>

с 'search' именем пути, указывающего на это представление.


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.

Вернуться на верх