0

I'm sending a query result from my database (combining 3 models) to one of my templates, allowing users to filter the output. Displaying all the information I want works just fine, until I try to paginate the results. Then I get empty QuerySet and 'Page 1 of 1' underneath. It completely baffles me as unprocessed set is fetched to the template without any disturbances.

Here's my views.py:

products =Product.objects.all()
out = Sets.objects.filter(
    ItemInSet__item__name__in=Product.objects.filter(metrics=1).values_list('product_name', flat=True)
).exclude(
    ItemInSet__item__name__in=Product.objects.filter(metrics=0).values_list('product_name', flat=True)
).distinct()

page = request.GET.get('page', 1)
paginator = Paginator(out, 10) # show 10 per page
try:
    out_p = paginator.page(page)
except PageNotAnInteger:
    out_p = paginator.page(1)
except EmptyPage:
    out_p = paginator.page(paginator.num_pages)

return render(request, 'item_list.html', {'products': products, 'results': out_p})

And my template:

<table id="id_item_list" >
{% if results.all  %}
    {% for result in results %}
        <tr>
        <form method="GET">
            {% csrf_token %}
            <ul>
                 <a href="/result/{{result.slug}} class="list-group-item list-group-item-action">
                <h4>{{ result.name|title }}</h4>
                <!-- and few more objects from Sets and ItemInSets etc. -->
                </a>               
            </ul>
        </form>
    </tr>
    {% endfor %}
{% else %}
    <p>No Sets matched your criteria.</p>
{% endif %}
</table>
<div class="pagination">
    <span class="step-links">
    {% if results.has_previous %}
        <a href="?page=1">&laquo; first</a>
        <a href="?page={{ results.previous_page_number }}">previous</a>
    {% endif %}
    <span class="current">Page {{ results.number }} of {{results.paginator.num_pages }}.</span>
    {% if results.has_next %}
        <a href="?page={{ results.next_page_number }}">next</a>
        <a href="?page={{ results.paginator.num_pages }}">last &raquo;</a>
    {% endif %}
    </span>
    </div>
</div>

The results are empty and pagination shows only 'Page 1 of 1'. No elements displayed whatsoever. When I pass set without pagination (out) it is fine. Is querying over multiple models causing this problem? I've seen the approach with itertools, yet combining query is not my immediate problem. Or is it?

Edit: following instructions provided in comments solved the issue. I've treated paginated data as a QuerySet, not as a Page, which in turn made me use unsupported method and shown no results, mea culpa.

Patrycja
  • 29
  • 6
  • 1
    i think you should to remove the if condition in the template `if results.all` because the paginator page does not have the method. – Brown Bear Jun 03 '19 at 14:28
  • 1
    and use the https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#for-empty to print `No Sets matched your criteria.` – Brown Bear Jun 03 '19 at 14:29
  • 1
    correct, a `Paginator` page is a `Page` which you can iterate over (like a list), not a `QuerySet`, therefore it doesn't have the method `all()`. See [here](https://docs.djangoproject.com/en/2.2/topics/pagination/#page-objects) – dirkgroten Jun 03 '19 at 14:33
  • Thank you for clearing up my misconception. I did not realise it while reading some code snippets I've used as reference. It works now. – Patrycja Jun 03 '19 at 15:37

0 Answers0