Saltar al contenido

paginaciones de uso de django-filter

Esta es el arreglo más correcta que encomtrarás compartir, pero estúdiala detenidamente y analiza si se adapta a tu trabajo.

Solución:

Esto funcionó para mí:

en mi plantilla en lugar de usar esto

  • i
  • Yo escribí esto:

    % if 'whatever_parameter_you_use_to_filter' in request.get_full_path %
       
  • % else %
  • i
  • % endif %

    Espero que ayude 🙂

    Para usar Django Filter y paginar el resultado filtrado, puede hacer lo siguiente:

    1. Cree una clase de filtro para su modelo:

      Sobre my_project/my_app/filters.py:

      import django_filters
      
      class MyModelFilter(django_filters.FilterSet):
          class Meta:
              model = MyModel
              # Declare all your model fields by which you will filter
              # your queryset here:
              fields = ['field_1', 'field_2', ...]
      
    2. Cada FilterSet el objeto tiene un .qs propiedad que contiene el conjunto de consultas filtradas e incluso puede anularlo si lo desea.

    3. Paginaremos el .qs propiedad de nuestro MyModelFilter:

      Sobre my_project/my_app/views.py:

      from . import filters
      from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
      
      def my_view(request):
          # BTW you do not need .all() after a .filter() 
          # local_url.objects.filter(global_url__id=1) will do
          filtered_qs = filters.MyModelFilter(
                            request.GET, 
                            queryset=MyModel.objects.all()
                        ).qs
          paginator = Paginator(filtered_qs, YOUR_PAGE_SIZE)
      
          page = request.GET.get('page')
          try:
              response = paginator.page(page)
          except PageNotAnInteger:
              response = paginator.page(1)
          except EmptyPage:
              response = paginator.page(paginator.num_pages)
      
          return render(
              request, 
              'your_template.html', 
              'response': response
          )
      

    ¡Y ahí lo tienes!


    PS_1: En mi experiencia, el filtro Django “juega” mejor con Django Rest Framework.

    PS_2: Si está a punto de utilizar DRF, he escrito un ejemplo sobre cómo usar la paginación en una vista basada en funciones que puede combinar fácilmente con una FilterSet:

    @api_view(['GET',])
    def my_function_based_list_view(request):
        paginator = PageNumberPagination()
        filtered_set = filters.MyModelFilter(
                           request.GET, 
                           queryset=MyModel.objects.all()
                       ).qs
        context = paginator.paginate_queryset(filtered_set, request)
        serializer = MyModelSerializer(context, many=True)
        return paginator.get_paginated_response(serializer.data)
    

    La parte más importante aquí es la cómo construyes tus URL en la plantilla.

    probablemente tienes

    % if pages.has_previous %
    
  • Prev
  • % endif %

    lo cual está perfectamente bien si lo está utilizando solo para cambiar entre los resultados paginados iniciales.

    Pero la parte complicada es cuando usas el django-fitler filtros, la cadena de consulta (esa parte después de la ‘?’) se vuelve totalmente nuevo key-valores pares, sin tener en cuenta su ?page=2 o similar.

    Por lo tanto, para que la paginación funcione con resultados filtrados, cuando haga clic en el botón “Siguiente” o “Anterior”, entre los key-valores de django-fitler también necesitas pasar el &page=5 como pareja.

    Como mencionó @stathoula, debe verificar si al menos uno de sus campos de filtro ya está presente en la cadena de consulta. Si es así, entonces necesita usar el ya presente key-pares de valores, seguidos del nuevo &page=3 par.

    Parece muy simple, pero tuve que hacer un pequeño truco para no repetir el &page=1 una y otra vez dentro de la cadena de consulta a medida que un usuario hace clic en las flechas.

    En mi caso, tengo ‘título’ como filtro, por lo que necesito verificar si ya está presente allí.

    Aquí hay un fragmento de lo que hice que funcionara perfectamente bien para mi proyecto.

    templates / pagination.html

    % with request.get_full_path as querystring % % endwith %

    Aquí está la vista, por si acaso:

    app / views.py

    def index(request):
        condo_list = Condo.objects.all().order_by('-timestamp_created')
        condo_filter = CondoFilter(request.GET, queryset=condo_list)
    
        paginator = Paginator(condo_filter.qs, MAX_CONDOS_PER_PAGE)
        page = request.GET.get('page')
    
        try:
            condos = paginator.page(page)
        except PageNotAnInteger:
            condos = paginator.page(1)
        except EmptyPage:
            condos = paginator.page(paginator.num_pages)
    
    
        return render(request, 'app/index.html', 
            'title': 'Home',
            'condos': condos,
            'page': page,
            'condo_filter': condo_filter,
        )
    

    Aquí hay un ejemplo de trabajo:

    .

    valoraciones y reseñas

    Si guardas alguna indecisión o disposición de modernizar nuestro noticia eres capaz de dejar una referencia y con deseo lo estudiaremos.

    ¡Haz clic para puntuar esta entrada!
    (Votos: 0 Promedio: 0)



    Utiliza Nuestro Buscador

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *