Django: django-tables2 paginación y filtrado

Tengo una mesa de trabajo generada por 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}) 

El código anterior devuelve una tabla con cientos de objetos que están cuidadosamente paginados con 10 elementos por página. Cuando hago clic en “Siguiente” en la parte inferior de la tabla, la paginación funciona bien y puedo navegar a través de diferentes páginas. Sin embargo, noté el siguiente comportamiento:

  • Haga clic en my_filter que muestra un subconjunto de la tabla original sin filtrar
  • Haga clic en “Siguiente” en la parte inferior de la tabla filtrada y aparecerá la segunda página de la tabla sin filtrar.
  • Haga clic en my_filter nuevamente para ver la segunda página de la tabla filtrada.

Me gustaría que el filtro persista mientras navega por diferentes páginas. Encontré una pregunta similar aquí . Esa solución indica que el código html necesita ser alterado. Sin embargo, en mi caso, django-tables2 está generando el html.

¿Cómo puedo implementar correctamente la paginación con filtrado utilizando django-tables2?

-Actualizar-

He intentado usar GET en lugar de 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}) 

Mi plantilla:

  {% csrf_token %} {{ my_filter }}   

Esto da como resultado que KeyError se deba a que my_choice no existe en GET. Como resultado, la página ni siquiera se carga.

¿Qué versión de django_tables2 estás usando? Verifiqué la fuente y vi que django_tables2 está usando una etiqueta de plantilla llamada querystring de querystring para crear los enlaces de paginación en la plantilla table.html . la etiqueta de la querystring actualiza la url actual con los parámetros de paginación. así que django_tables2 soporta paginación + filtrado fuera de la caja (eso es lo que recordé).

Intente actualizar a la última versión de django_tables2 y asegúrese de estar usando la plantilla table.html predeterminada para representar sus tablas.

¿También está enviando su formulario de filtro con GET o POST? Por favor, asegúrese de que lo envíe con GET!

Finalmente, por favor, eche un vistazo a mi respuesta a esta pregunta Tablas de Django – Filtrado de columnas

actualización: eché un vistazo más de cerca al código que publicaste: en primer lugar, estás pasando los datos de la publicación al filtro: no puedes usar la POST para eso, la POST solo se debe usar para acciones que modifican tus datos. También vi que no filtres nada, ¡sino que pasas .all () a la tabla! ¿Dónde se realiza el filtrado real? ¡Debes pasar los datos filtrados a la tabla como describo en la respuesta anterior!

actualización 2: el problema con su vista es que cuando visita la página por primera vez, el diccionario GET no contiene el atributo my_choice por lo que generará una excepción cuando intente acceder al atributo my_choice través del operador [] , por lo que debería verificar Si realmente existe usando, por ejemplo, .get() , algo como esto:

 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}) 

Lo anterior debería funcionar, sin embargo, al hacer el filtrado de consultas usted mismo, está violando casi todas las filosofías de diseño de django .

Por eso le dije que leyera mi otra respuesta a la pregunta similar ( Tablas de Django – Filtrado de columnas ) en la que recomiendo usar django-filter, que es un paquete que se usa explícitamente para filtrar conjuntos de consultas. Verifique la documentación o mi respuesta para ver cómo se puede usar (Me encantaría ayudarlo si tiene alguna pregunta).

Además, hay una serie de otros problemas menores con su código:

  • No es necesario que compruebe si el request.method es GET ; siempre será GET ya que no hará ningún POST s

  • No debe incluir {{ csrf_token }} a su plantilla, solo se necesita para POST .

  • La clase TestFilter es en realidad un Form , por eso recomiendo nombrarlo TestFilterForm o algo similar: si usó django-filter, crearía una clase FilterSet que se llamaría TestFilter . El nombre correcto de las clases es muy importante, cuando vi su código por primera vez, ¡pensé que la clase TestFilter era un FilterSet y no un Form !