Использование сортировки и фильтрации в QuerySet - PullRequest
1 голос
/ 17 июня 2011

У меня есть список пользовательских профилей, которые я хочу иметь возможность сортировать и фильтровать.

Мне удалось сделать это вручную, вручную введя URL-адреса, но я не смог закодировать страницу шаблона, чтобы разрешить сохранение ранее примененного фильтра или сортировки.Вот код URL и шаблон, который у меня есть на данный момент -

# in urls
url(r'^talent/filter\:(?P<position>[A-Za-z]+)/sort\:(?P<sort>[A-Za-z]+)$', 'talent_filter', name='talent_filter_sort'),
url(r'^talent/filter\:(?P<position>[A-Za-z]+)/$', 'talent_filter', name='talent_filter'),
url(r'^talent/sort\:(?P<sort>[A-Za-z]+)/$', 'talent_sort', name='talent_sort'),
url(r'^talent/$', 'talent', name='talent'),

# in template
<ul>
    <li>SORT BY:</li>
    <li><a href = "{% url talent_sort sort='alphabetical'%}">Alphabetical</a></li>
    ...
</ul>
<ul>
    <li><a href = '{% url talent_filter position=position%}'>{{ position }}</a></li>
    ... 
</ul>

В настоящее время, если я нахожусь на странице талантов (не отсортированных, нефильтрованных) и выбираю фильтр результатов, он вернется talent/filter:filter.Затем, если я выберу сортировку результатов, она (очевидно) переходит к talent/sort:sort, удаляя предыдущий фильтр.

Что я хочу сделать, так это то, что если я в данный момент на talent/filter:filter и выбираю метод сортировки, он перейдет к talent/filter:filter/sort:sort, и если я уже отсортировал результаты (talent/sort:sort), и нажмитена фильтре, это также приведет меня к talent/filter:filter/sort:sort.Как бы я этого достиг.Спасибо.

Ответы [ 2 ]

2 голосов
/ 17 июня 2011

Я думаю, что одним из способов достижения этого является сохранение в сеансе флага, который указывает, какой должна быть сортировка или фильтрация. Например, что-то вроде ниже может быть использовано для сохранения состояния вашего выбора сортировки.

request.session['TALANT_SORT'] = "alphabetical"
request.session['TALENT_FILTER'] = "top_ten" 

И тогда ваши представления могут проверить наличие сеансовых ключей и соответственно применить фильтр.

qs = models.MyModel.objects.all()

sort = request.session.get('TALENT_SORT', None)
if sort in ["alphabetical", "created_date"]:
    qs = qs.order_by(sort)

myfilter = request.session.get("TALENT_FILTER", None)
if myfilter in ["top_ten","bottom_ten"]:
    qs = qs.filter( .... ) 

....

Сортировка и фильтрация могут сохраняться в разных запросах.

Если вы хотите удалить сортировку или фильтр, возможно, вы можете удалить сеансовые ключи в представлении в зависимости от действий пользователя:

try:
    del request.session['TALENT_SORT']
    del request.session['TALENT_FILTER']
except KeyError: 
    pass 

Кроме того, в зависимости от ваших требований, вы можете рассмотреть возможность объединения 2-х URL-адресов в 1 и просто использовать параметры GET для активации сортировки.

request.GET.get('sort',None)
....
request.GET.get('filter', None)
....

В этих примерах, возможно, можно использовать более строгую строгость, но это идея. Надеюсь это поможет. Джо

1 голос
/ 17 июня 2011

Несмотря на то, что это немного против того, что представляет собой django, лучший подход к заданным пользователем сортировкам / фильтрам, если использовать переменные GET.Таким образом, ваши URL-адреса будут выглядеть следующим образом:

/ talent /? Filter = foo & sort = bar

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

Что-то вроде: Алфавитный

Если вы действительно чувствуете, что необходимо использовать захваченные URL-параметры, вам нужно настроить URL-адреса для обработки всех условий (сортировки, фильтрации, ниустановить, и оба установить).И тогда в ваших шаблонах вам понадобится куча операторов if для выбора правильного URL и параметров.

Как я уже говорил, этот тип ситуации гораздо лучше обрабатывается с помощью параметров GET.

...