Django Paginate, returns incorrect number of items on the page

I asked this question on StackOverflow (https://stackoverflow.com/questions/63442732/django-paginate-returns-incorrect-number-of-items-on-the-page), just wanted to share this here also. If this is bad practice, please let me know.

I am trying to use Django’s built-in Paginate method to limit 6 items per page. After setting up the paginate, I get a different number of items on each page

  • first page - 1 item
  • second - 3 items, etc

Here is my set up:

models.py

class Project(models.Model):
    title = models.CharField(max_length=100, unique=True)
    url = models.URLField(unique=True)
    date_added = models.DateTimeField(auto_now_add=True)
    ...
    class Meta:
        ordering = ["-date_added"]
    ...

views.py

class ProjectListView(ListView):
    model = Project
    paginate_by = 6 
    template_name = "home.html"

home.html

{% extends 'base.html' %}
{% load static %}

{% block content %}
<div>
  {% for site in page_obj %}
  <p>{{ site.title }}</p>
  {% endfor %}
</div>

<!-- Code below is from the official -->
<div class="pagination">
  <span class="step-links">
      {% if page_obj.has_previous %}
          <a href="?page=1">&laquo; first</a>
          <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>
          <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
      {% endif %}
  </span>
</div>
{% endblock content %}

I tried doing this in the shell, like in the official documentation and there results were fine:

shell

In [3]: projects = Project.objects.all()                                                                                                                                                                                         
In [4]: p = Paginator(projects, 6)

In [9]: page1 = p.page(1)
In [21]: len(page1.object_list)                                                                                                                                                                                                  
Out[21]: 6

In [22]: page3 = p.page(3)                                                                                                                                                                                                       
In [23]: len(page3.object_list)                                                                                                                                                                                                  
Out[23]: 6

What am I doing wrong?

If you need any additional info, please let me know.

Thanks, for the help in advance.

I cannot replicate this issue. I’ve taken your model (removing the URL field since it’s not being used), removed the extends and block clauses from the templates - but otherwise using as is, and using your view. I wired up a url in my urls file, made up some data, and ran it.
Everything works exactly as expected.
This leads me to believe there’s either some questionable data or something external to what you’ve posted causing the problem.

As a simple test to rule out any “title” issues, I’d replace this line:
<p>{{ site.title }}</p>
with something like this, just to see if the right number of entries are being rendered:
<p>*****</p>

1 Like

Thanks, Ken. I tested with your suggested method and it should work.

I understand what the error is now. In my models.py I have a boolean field which determines if the item should be published or not. Only 2 out of the latest 6 entries are published.

I have to modify the queryset to exclude all the items that have False as their published field.

Thanks for the help Ken!