How to create pagination in Django?

2019-09-22 13:06发布

问题:

I follow this Document of djangoproject.com : https://docs.djangoproject.com/en/1.8/topics/pagination/. But it is too simple. It is only Next and Previous button.

Now I want create pagination with more features such as http://i.imgur.com/ZiFeAqG.jpg.

This is code:

View.py

def hire(request):

hire_article_list = hire_article.objects.all().order_by('-id')
#hire_article_list = hire_article.objects.order_by("-publication_date")

paginator = Paginator(hire_article_list, 2) # Show 25 contacts per page

page = request.GET.get('page')
try:
    hire_article_s = paginator.page(page)

except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    hire_article_s = paginator.page(1)
except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.

    hire_article_s = paginator.page(paginator.num_pages)

#return render_to_response('hire/list.html', {"page_list": page_list})
context = {'hire_article_s': hire_article_s}
return render(request, 'hire/list.html', context)

list.html

{% for j in hire_article_s %}
    {# Each "j" is a page_list  model object. #}
    <li><a href="/hire/{{ j.slug }}-{{j.id}}">{{ j.hiring}}</a></li>
{% endfor %}

                {% if hire_article_s.has_previous %}
                    <a href="?page={{ hire_article_s.previous_page_number }}">previous</a>
                {% endif %}

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

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

        </span>
</div>

回答1:

I had a similar need last week and found this super useful gist (https://gist.github.com/jsatt/8183993) that worked fine (though I'm not sure why it wouldn't work till I put request in the function parameters). It's a subclass of django's Paginator function. You could put this in a utility file and call it whenever you want to use Paginate with the range.

For instance, I had mine in a file called utils.py, which is in my core app.

views.py

from core.utils import paginate

def hire(request):

    hire_article_list = hire_article.objects.all().order_by('-id')
    '''
    Show 25 contacts per page, with a page range of 5, which means if you are
    on page 8, it shows links to pages 6,7,8,9,10.
    '''
    hire_article_s = paginate(request, hire_article_list, 25, 5) 

    context = {'hire_article_s': hire_article_s}
    return render(request, 'hire/list.html', context)

list.html

{% if hire_article_s.has_previous %}
     <a href="?page={{ hire_article_s.previous_page_number }}">previous</a>
{% endif %}

{% for range in hire_article_s.neighbor_range %}
    {% if range == hire_article_s.number %}
       <li class="pagination__item active ">{{ range }}</li>
    {% else %}
       <li class="{% if range == hire_article_s.number %}active {% endif %}"><a href="?page={{ range }}">{{ range }}</a></li>
    {% endif %}
{% endfor %} 

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

Hope this helps.

UPDATE

The above code has been edited a bit. I've added the context and the template format. Note that I'm using a loop to go through {{ hire_article_s.neighbor_range }} and print out the page numbers. I also do a check to highlight the current page's number. the This should work, as it's pretty much my own code with your own variable names.