1

I know a related question has been asked before here: how can I use pagination with django_filter but I really tried to make it work with mine but because I use a custom LinkWidget or class i find it hard to included the pagination in to my ResultsFilter class or even get it to work with views and template.

Here is my code so far:

filter.py

# I didn't do much just changed so filters would be displayed as text/url just like django admin works instead of FORMS
# and i also add style to the returned <li>

class MyLinkWidget(widgets.LinkWidget):
    """docstring for ClassName"""
    def __init__(self, **karg):
        # super().__init__()
        super(widgets.LinkWidget, self).__init__(**karg)
    def option_string(self):
        return '<li class="list-group-item list-group-item-dark"><a%(attrs)s href="?%(query_string)s">%(label)s</a></li>'

class ResultsFilter(FilterSet):
    important = AllValuesFilter(widget=MyLinkWidget(attrs={"class":"list-group"}))
    viewed = AllValuesFilter(widget=MyLinkWidget(attrs={"class":"list-group"}))

    class Meta:
        model = Results
        fields = ['viewed', 'important',]

views.py

class ResultView(ListView):
    paginate_by = 3
    model = Results
    template_name = 'results_filter.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = ResultsFilter(self.request.GET, queryset=self.get_queryset())
        return context

and finally template file is:

results_filter.html

<div class="filter_header">
  <span class="l">Filter by Viewed</span>
  {{filter.form.viewed}}
</div>

<div class="filter_header">
  <span class="l>Filter by Viewed</span>
  {{filter.form.important}}
</div>

<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

EDIT

So basically, when i am at http://127.0.0.1:8000/ it shows all records ignoring paginate_by = 3 and i click next url becomes http://127.0.0.1:8000/?page=2 but still showing all records. Which means pagination is not working but clicking filter for important or entering url as http://127.0.0.1:8000/results/?page=3&important=False. I noticed only data i.e (20 records) where importance is False are shown but i need just 3 page records so i can click next to view others.

Bottom line is i think paginate_by is not linked to the queryset returned by Django-Filter based on my classes above

Jide Koso
  • 415
  • 5
  • 17
  • What exactly is not working in your code? What is happening and how is that different from what you expect to happen? – Ralf Nov 09 '19 at 10:27
  • Also, as is easy to see with the code highlighting, your HTML is missing an closing quotation mark in the line ` – Ralf Nov 09 '19 at 10:29
  • @Ralf thanks pagination is the problem, I have added more information – Jide Koso Nov 09 '19 at 10:53
  • [This related answer](https://stackoverflow.com/a/44541540/9225671) suggests using an explicit `Paginator` on the filtered queryset – Ralf Nov 09 '19 at 11:12

1 Answers1

0

This is a little late, but try this:

from django_filters.views import FilterView
    
class ResultView(FilterView):
    filterset_class = ResultsFilter
    paginate_by = 3

Then in you html use object_list, it will contain the paginated results.

{% for object in object_list %}
...
{% endfor %}
Radjin
  • 246
  • 3
  • 4