0

I am looking to implement Pagination with Django-Filter's function based view. I currently have the search function working, but have not been able to find documentation online on how to implement pagination with Django-filter; haven't been able to get it working with references i've found online.

What I have so far:

views.py

from django.shortcuts import render
from .models import Stock
from .filters import StockFilter

def home(request):
  return render(request, 'stockwatcher/home.html', {'title': 'Home'})

def stock_search(request):
  f = StockFilter(request.GET, queryset=Stock.objects.all())
  return render(request, 'stockwatcher/search_results.html', {'filter': f})

filters.py

import django_filters
from .models import *

class StockFilter(django_filters.FilterSet):
  senator = django_filters.CharFilter(field_name='senator' ,lookup_expr='icontains')
  ticker = django_filters.CharFilter(field_name='ticker', lookup_expr='iexact')
  
  class Meta:
    model = Stock
    fields = [
      'senator',
      'ticker'
    ]
    exclude = [
      'asset_description',
      'asset_type',
      'amount',
      'type',
      'transaction_date',
    ]

urls.py

from django.urls import path, re_path
from . import views

urlpatterns = [ path('', views.home, name="stockwatcher-home"),
                path('stocks/', views.stock_search, name="stockwatcher-stocks"),
                path('about/', views.about, name="stockwatcher-about")]


search_results.html

{% extends "stockwatcher/base.html" %}
{% block content %}
{% load widget_tweaks %}


<div class="container">
  <div class="row" style="padding: 50px;">
    <form method="get">
      {{ filter.form.as_p }}
      <input type="submit" />
    </form>
  </div>

    <div class="row">
    {% for stock in filter.qs %}
    <div class="col-4">
      <div class="card text-white bg-info mb-3" style="max-width: 18rem;">
        <div class="card-header">{{stock.transaction_date}}</div>
        <div class="card-body">
          <h5 class="card-title" style="color: white"> {{stock.ticker}} </h5>
          <p class="card-text">{{stock.senator}} - {{stock.type}}</p>
        </div>
      </div>
    </div>
    {% endfor %}
</div>

<!--{% if is_paginated %}-->
<!--  {% if page_obj.has_previous %}-->
<!--    <a class="btn btn-outline-info mb-4" href="?page=1">First</a>-->
<!--    <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>-->
<!--  {% endif %}-->

<!--  {% if page_obj.has_next %}-->
<!--    <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>-->
<!--    <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>-->
<!--  {% endif %}-->
<!--{% endif %}-->

{% endblock content %}
SL.
  • 15
  • 3

2 Answers2

1

try this views.py

from django.shortcuts import render
from .models import Stock
from .filters import StockFilter
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def home(request):
    return render(request, 'stockwatcher/home.html', {'title': 'Home'})

def stock_search(request):
    f = StockFilter(request.GET, queryset=Stock.objects.all())
    paginator = Paginator(f.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, 'stockwatcher/search_results.html', {'filter': response,'filter_form':f})

your template

{% extends "stockwatcher/base.html" %}
{% block content %}
{% load widget_tweaks %}


<div class="container">
  <div class="row" style="padding: 50px;">
    <form method="get">
      {{ filter_form.form.as_p }}
      <input type="submit" />
    </form>
  </div>

    <div class="row">
    {% for stock in filter %}
    <div class="col-4">
      <div class="card text-white bg-info mb-3" style="max-width: 18rem;">
        <div class="card-header">{{stock.transaction_date}}</div>
        <div class="card-body">
          <h5 class="card-title" style="color: white"> {{stock.ticker}} </h5>
          <p class="card-text">{{stock.senator}} - {{stock.type}}</p>
        </div>
      </div>
    </div>
    {% endfor %}
</div>

<div >
 <span class="step-links">
 {% if filter.has_previous %}
 <a href="?page={{ filter.previous_page_number }}"><span style="font-size:30px;float:left;" class="glyphicon glyphicon-arrow-left"> left</span></a>
 {% endif %}
 {% if filter.has_next %}
 <a href="?page={{ filter.next_page_number }}"> <span style="font-size:30px;float:right;" class="glyphicon glyphicon-arrow-right">right </span></a>
 {% endif %}
 </span>
</div>
{% endblock content %}

do not forget to put a number in your_page_size

Thierno Amadou Sow
  • 2,523
  • 2
  • 5
  • 19
  • This seems to get the pagination with search filtering working. One thing I noticed though is that the search boxes do not show up. (I tested the search by adding the search parameters at the end of the URL). `{{ filter.form.as_p }}` From my knowledge, this snippet should be automatically creating the input boxes based on the StockFilter's fields. I currently only see the submit button which is strange... Maybe im missing something. – SL. Nov 19 '21 at 02:30
  • @SL. Is it working for you ? – Thierno Amadou Sow Nov 19 '21 at 02:32
  • Sorry, just edited the comment. This is what im seeing https://imgur.com/a/DULFhBR . It doesn't look like its rendering the `{{ filter.form.as_p }}` correctly for some reason. – SL. Nov 19 '21 at 02:42
  • @SL. i just updated my views and the template try it. – Thierno Amadou Sow Nov 19 '21 at 02:50
  • Ah, yeah -- that works! Thanks. Is there any documentation you referenced for this? Think i need to read it over! :) Update: Nevermind -- I see what you did, this makes sense. Thanks! – SL. Nov 19 '21 at 02:53
  • @SL. i never used django-filter before.i know about only django padignation (https://docs.djangoproject.com/en/3.2/topics/pagination/) – Thierno Amadou Sow Nov 19 '21 at 02:55
0

have a look at this, I hope you should get your answers from here

django-filter use paginations

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 18 '21 at 06:17