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 так как вы не будете делать ничего POSTs

  • вы не следует включать {{ csrf_token }} для вашего шаблона-это необходимо только для POST.

  • на TestFilter класс-это на самом деле Form вот почему я рекомендую назвать его TestFilterForm или что-то подобное -- если бы вы использовали django-filter, вы бы создали FilterSet класс, который будет называться TestFilter. Правильное название классов очень важно, когда я впервые увидел ваш код, я подумал, что TestFilter класс был a FilterSet, а не Form !