DiggPaginator update

Here’s an update (link goes to DjangoSnippets) to the paginator code I posted a while back (link goes to the old version). The main thing is the deprecation warning, which is now gone.

In particular:

  • Previously, a custom base class was used that implemented a stateful, page-aware paginator. Now that Django’s new Paginator class does essentially the same thing (only better), this base class is gone for good.
  • Note though that Django’s version uses different attribute names to provide the data, so you’ll likely have to update your code and templates (e.g. start_index instead of first_on_page, has_other_pages instead of is_paginated, and more).
  • The custom page ranges that DiggPaginator adds are page-specific and thus attributes of the Page object. Don’t confuse this with the page_range attribute on the paginator instance itself, which is the full range, as provided by the Django implementation.
  • Note the new QuerySetDiggPaginator class – since Django splits that functionality, so do we.
  • Following the example of Django’s new paginator, InvalidPage exceptions are no longer automatically converted to 404s – do that yourself.
  • There are two cool new options, softlimit and align_left, which are useful when paginating data with possibly uncertain length (like a search result). See the comments for details.

Usage example:

objects = MyModel.objects.all()
paginator = DiggPaginator(objects, 10, body=6, padding=2)
return render_to_response('template.html', {'page': paginator.page(7)}
{% if page.has_next %}{# pagelink page.next_page_number #}{% endif %}
{% for num in page.page_range %}
   {% if not num %} ...  {# literally dots #}
   {% else %}{# pagelink num #}
   {% endif %}
{% endfor %}

12 thoughts on “DiggPaginator update

  1. Hi,
    first of all thanks for this script!
    Why is the QuerySetDiggPaginator empty? I need to paginate a QuerySet 😉 If i use the class DiggPaginator it works, but there is no “LIMIT OFFSET…” on my Querys. This is a performance killer.

    Thanks in advance,
    io_error

    Like

  2. Bernhard, QuerySetDiggPaginator should work, it subclasses both DiggPaginator and Django’s QuerySetPaginator. Give it a try, and please let me know if it doesn’t work (or even if it does – you’ve got me bit worried now ;)).

    Like

  3. hello,
    thanks for sharing this code. i am trying to integrate your code in to my template used from django.views.generic.list_detail.object_list. have you used your paginator in a similar context?

    Like

  4. one more thing:

    you can avoid floating point operations:

    max_padding = int(math.ceil(self.body/2.0)-1)
    is the same as
    max_padding = (self.body + 1) / 2 – 1

    in general: (K + N – 1) / N == math.ceil(float(K) / float(N)), where K and N are integers

    and

    math.floor(number+body/2.0)
    is the same as
    number+body / 2

    Like

    1. Konstantin, wrt the the object_list generic view: Well, it seems possible, from a look at the code, if you just don’t use the views own pagination features; looks like you’d have to pass paginate_by=False and an empty queryset, and pass the DiggPaginator instance through extra_context.

      It’s just that pagination is pretty much the only thing that view does, so I’m not sure the above makes all that much sense. You’d be better off just using your own view.

      Thanks for the tip about the math operations. You’re right, of course, I’m slightly stupefied that I wrote the code the way I did. I’m not going to update the snippet, but I will update my repository, which you can find here: http://bitbucket.org/miracle2k/djutils/src/tip/djutils/pagination.py

      Like

  5. Hi,

    Could you please post here what the code within the template should look like? Just the basic flow of how to output the links, not the styling.

    Thanks and cheers for a great snippet.

    Like

  6. Re my previous comment:

    Never mind, I got it, but it would be useful to post that info anyway. Thanks again.

    Like

Leave a comment