Django: Django-разбиение на страницы и фильтрация tables2
у меня есть рабочая таблица, сгенерированная django-tables2:
my_filter = TestFilter(request.POST)
table = TestTable(TestObj.objects.all(), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
приведенный выше код возвращает таблицу с сотнями объектов, которые аккуратно разбиты на страницы с 10 элементами на странице. Когда я нажимаю "далее" в нижней части таблицы, разбиение на страницы работает хорошо, и я могу перемещаться по разным страницам. Однако, я заметил следующее поведение:
- нажать на кнопку
my_filter
который отображает подмножество исходной нефильтрованной таблицы - нажмите "Next" на нижняя часть отфильтрованной таблицы приведет к отображению 2-й страницы нефильтрованной таблицы
- нажать на кнопку
my_filter
снова отображает 2-ю страницу отфильтрованной таблицы
Я хотел бы, чтобы фильтр сохранялся при навигации по разным страницам. Я нашел аналогичный вопрос здесь. Это решение указывает на необходимость изменения html-кода. Однако в моем случае django-tables2 генерирует html.
как я могу правильно реализовать разбиение на страницы с фильтрацией с использованием django-tables2?
-обновить-
Я пробовал использовать GET вместо POST:
if request.method == 'GET':
my_filter = TestFilter(request.GET)
my_choice = my_filter.data['my_choice']
table = TestTable(TestObj.objects.filter(choice=my_choice), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
мой шаблон:
<form action="" method="get"> {% csrf_token %}
{{ my_filter }} <input type="submit" value="Apply Filter"/>
</form>
это приводит к KeyError из-за my_choice
не существует в GET. В результате страница даже не загружается.
1 ответов
какую версию django_tables2 вы используете? Я проверил источник и увидел, что django_tables2 использует тег шаблона с именем querystring
для создания ссылок разбиения на страницы в table.html
шаблон. the querystring
tag обновления текущий url с параметрами подкачки. таким образом, django_tables2 поддерживает разбиение на страницы + фильтрацию из коробки (это то, что я запомнил).
пожалуйста, попробуйте обновить до последней версии django_tables2 и убедитесь, что вы используете значение по умолчанию table.html
шаблон для рендеринга таблиц.
также вы отправляете свою форму фильтра с GET или POST? Пожалуйста, убедитесь, что отправить его с GET!
наконец-то, пожалуйста, взгляните на мой ответ на этот вопрос Таблицы Django-Фильтрация Столбцов
обновление: я внимательно посмотрел в коде, который вы опубликовали: прежде всего, вы передаете данные post в фильтр: вы не можете использовать POST для этого, POST должен быть используется только для действий, изменяющих данные. также я видел, что вы ничего не фильтруете, а вместо этого проходите.все к столу! где выполняется фактическая фильтрация? вы должны передать отфильтрованные данные в таблицу, как я описываю в ответе выше!
обновление 2:
Проблема с вашим представлением заключается в том, что при первом посещении страницы GET
словарь не содержит my_choice
атрибут, поэтому он будет выдавать исключение при попытке доступа к my_choice
атрибут через []
оператор, поэтому вы должны проверить, существует ли он на самом деле, используя, например,.get()
, что-то вроде этого:
my_filter = TestFilter(request.GET)
my_choice = my_filter.data.get('my_choice') # This won't throw an exception
if my_choice: # If my_choice existed on the GET dictionary this will return non-null value
table = TestTable(TestObj.objects.filter(choice=my_choice), order_by="-my_date")
else:
table = TestTable(TestObj.objects.all(), order_by="-my_date")
RequestConfig(request, paginate={"per_page": 10}).configure(table)
return render(request, 'test_app/index.html', {'table': table, 'my_filter': my_filter})
выше должно работать, однако, делая фильтрацию запросов самостоятельно -вы нарушаете почти все философия дизайна django !
вот почему я сказал вам прочитать мой другой ответ на аналогичный вопрос (Таблицы Django-Фильтрация Столбцов), в котором я рекомендую используя Джанго-фильтр который является пакетом, явно используемым для фильтрации запросов. Пожалуйста, проверьте документацию или мой ответ, чтобы узнать, как его можно использовать (я буду рад помочь, если у вас есть вопросы).
кроме того, существует ряд других незначительных проблем с вашим кодом:
вам не нужно проверять, если
request.method
иGET
- Она всегда будетGET
так как вы не будете делать ничегоPOST
sвы не следует включать
{{ csrf_token }}
для вашего шаблона-это необходимо только дляPOST
.на
TestFilter
класс-это на самом делеForm
вот почему я рекомендую назвать егоTestFilterForm
или что-то подобное -- если бы вы использовали django-filter, вы бы создалиFilterSet
класс, который будет называтьсяTestFilter
. Правильное название классов очень важно, когда я впервые увидел ваш код, я подумал, чтоTestFilter
класс был aFilterSet
, а неForm
!