This is a very basic paginator for CouchDB ViewResults. It's usage is similar to the django one.
CouchPaginator is almost like the django version with one exception: It's constructor needs an additional argument pages_view
which is either a reduce result or an integer which holds the total number of objects across all pages.
Example Map/Reduce for pages:
map = function(doc) { if(doc.type=="application" || doc.type=="inquiry"){ emit([doc.meta.user.toLowerCase(), doc.type], 1); } reduce = function (doc, value, rereduce){ return sum(value); }
SimpleCouchPaginator is much simpler and needs no total number and can only paginate by "next" and "previous" page. Use this if you don't have an reduce view which tells you the amount of total object.
An Example setup of CouchDB with django can be found at: Eric Florenzanos post about django+couchdb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | # -*- coding: utf-8 -*-
from math import ceil
from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage
class CouchPaginator(Paginator):
"""Allows pagination of couchdb-python ViewResult objects. """
def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True, pages_view=None):
self.per_page = per_page
self._object_list = object_list
self.orphans = orphans
self.allow_empty_first_page = allow_empty_first_page
self._pages_view = pages_view
self._num_pages = None
def page(self, number):
"Returns a Page object for the given 1-based page number."
self._number = self.validate_number(number)
skip = self._number * self.per_page - self.per_page
### FIXME it would be nice to be compatible with django
### and allow [from:to] syntax
self._object_list.options['count'] = self.per_page + 1
self._object_list.options['skip'] = skip
return Page(self.object_list, self._number, self)
@property
def _count(self):
"""Implementation specific object count (overall)"""
if self._pages_view:
if isinstance(self._pages_view, int):
count = self._pages_view
else:
count = self._pages_view.rows[0].get("value", None)
else:
count = None
return count
@property
def object_list(self):
"""Returns a list of results or raises EmptyPage"""
if self._object_list:
return list(self._object_list)[:self.per_page]
else:
raise EmptyPage('That page contains no results')
class SimpleCouchPaginator(CouchPaginator):
"""Allows very simple page by page pagination with CouchDB ViewResults
use SimpleCouchPaginator only if you don't have the absolute object count.
If you have it CouchPaginator would be fine.
"""
def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True):
self.per_page = per_page
self._object_list = object_list
self.orphans = orphans
self.allow_empty_first_page = allow_empty_first_page
self._num_pages = None
return super(SimpleCouchPaginator, self).__init__(object_list, per_page,
orphans=orphans, allow_empty_first_page=allow_empty_first_page)
def validate_number(self, number):
"Validates the given 1-based page number."
try:
number = int(number)
except ValueError:
raise PageNotAnInteger('That page number is not an integer')
if number < 1:
raise EmptyPage('That page number is less than 1')
return number
def _get_count(self):
return False
@property
def num_pages(self):
return False
@property
def object_count(self):
return len(list(self._object_list))
@property
def next(self):
if self.has_next:
return self._number + 1
else:
return None
@property
def previous(self):
if self.has_previous:
return self._number - 1
else:
return None
@property
def has_next(self):
return self.object_count > self.per_page
@property
def has_previous(self):
return self._number > 1
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.