Home > Blockchain >  Implementing Pagination with Django-Filter
Implementing Pagination with Django-Filter

Time:11-18

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

CodePudding user response:

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()).qs
    paginator = Paginator(f, 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})

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.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

CodePudding user response:

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

django-filter use paginations

  • Related