From: Joseph Spiros Date: Wed, 11 Aug 2010 20:10:54 +0000 (-0400) Subject: Merge branch 'master' of git://github.com/melinath/philo X-Git-Tag: philo-0.9~41 X-Git-Url: http://git.ithinksw.org/philo.git/commitdiff_plain/a10d536d08f92d270e9ddcb240b7eded89d0e707?hp=e3037e2cf8a7ad3d0c3dba94083d1753301f581b Merge branch 'master' of git://github.com/melinath/philo * 'master' of git://github.com/melinath/philo: Paginator returns page.object_list as objects if a page exists. Implements render_to_string on Page model for cases where this is used to render i.e. emails (Feature #18) Unimplemented PaginationProxy; moved pagination from penfield to core. Multiview will now pass node and extra_context to any view that takes kwargs. Fixes bug #10 Added forgotten import of EmptyPage. Introduced the PaginationProxy object to simplify use in templates. Revised penfield's pagination helper to work more generically. --- diff --git a/contrib/penfield/models.py b/contrib/penfield/models.py index 2a10e26..957c277 100644 --- a/contrib/penfield/models.py +++ b/contrib/penfield/models.py @@ -6,7 +6,7 @@ from django.conf.urls.defaults import url, patterns from django.core.urlresolvers import reverse from django.http import Http404, HttpResponse from datetime import datetime -from philo.contrib.penfield.utils import paginate +from philo.utils import paginate from philo.contrib.penfield.validators import validate_pagination_count @@ -130,15 +130,10 @@ class BlogView(MultiView): return base_patterns + entry_patterns def index_view(self, request, node=None, extra_context=None): - entries = self.blog.entries.all() - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None + paginator, page, entries = paginate(self.blog.entries.all(), self.entries_per_page, request.GET.get('page', 1)) context = {} context.update(extra_context or {}) - context.update({'blog': self.blog, 'entries': entries, 'paginated_page': paginated_page}) + context.update({'blog': self.blog, 'paginator': paginator, 'paginated_page': page, 'entries': entries}) return self.index_page.render_to_response(node, request, extra_context=context) def entry_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None): @@ -168,14 +163,11 @@ class BlogView(MultiView): entries = entries.filter(date__month=month) if day: entries = entries.filter(date__day=day) - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None + + paginator, page, entries = paginate(entries, self.entries_per_page, request.GET.get('page', 1)) context = {} context.update(extra_context or {}) - context.update({'blog': self.blog, 'year': year, 'month': month, 'day': day, 'entries': entries, 'paginated_page': paginated_page}) + context.update({'blog': self.blog, 'year': year, 'month': month, 'day': day, 'paginator': paginator, 'paginated_page': page, 'entries': entries}) return self.entry_archive_page.render_to_response(node, request, extra_context=context) def tag_view(self, request, tag_slugs, node=None, extra_context=None): @@ -196,14 +188,10 @@ class BlogView(MultiView): if entries.count() <= 0: raise Http404 - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None + paginator, page, entries = paginate(entries, self.entries_per_page, request.GET.get('page', 1)) context = {} context.update(extra_context or {}) - context.update({'blog': self.blog, 'tags': tags, 'entries': entries, 'paginated_page': paginated_page}) + context.update({'blog': self.blog, 'tags': tags, 'paginator': paginator, 'paginated_page': page, 'entries': entries}) return self.tag_page.render_to_response(node, request, extra_context=context) def tag_archive_view(self, request, node=None, extra_context=None): diff --git a/contrib/penfield/utils.py b/contrib/penfield/utils.py deleted file mode 100644 index 5df800c..0000000 --- a/contrib/penfield/utils.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.core.paginator import Paginator, InvalidPage, EmptyPage - - -def paginate(request, entries, entries_per_page): - paginator = Paginator(entries, entries_per_page) - try: - page_number = int(request.GET.get('page', '1')) - entries = paginator.page(page_number).object_list - page = paginator.page(page_number) - except ValueError: - page_number = 1 - entries = paginator.page(page_number).object_list - page = paginator.page(page_number) - try: - entries = paginator.page(page_number).object_list - page = paginator.page(page_number) - except (EmptyPage, InvalidPage): - entries = paginator.page(paginator.num_pages).object_list - page = paginator.page(page_number) - return page \ No newline at end of file diff --git a/models/nodes.py b/models/nodes.py index f84565d..56cbb12 100644 --- a/models/nodes.py +++ b/models/nodes.py @@ -73,12 +73,12 @@ class MultiView(View): subpath = "" subpath = "/" + subpath view, args, kwargs = resolve(subpath, urlconf=self) - view_args = getargspec(view)[0] - if extra_context is not None and 'extra_context' in view_args: + view_args = getargspec(view) + if extra_context is not None and ('extra_context' in view_args[0] or view_args[2] is not None): if 'extra_context' in kwargs: extra_context.update(kwargs['extra_context']) kwargs['extra_context'] = extra_context - if 'node' in view_args: + if 'node' in view_args[0] or view_args[2] is not None: kwargs['node'] = node return view(request, *args, **kwargs) diff --git a/models/pages.py b/models/pages.py index ff8e876..9d02c79 100644 --- a/models/pages.py +++ b/models/pages.py @@ -98,11 +98,17 @@ class Page(View): template = models.ForeignKey(Template, related_name='pages') title = models.CharField(max_length=255) - def render_to_response(self, node, request, path=None, subpath=None, extra_context=None): + def render_to_string(self, node=None, request=None, path=None, subpath=None, extra_context=None): context = {} context.update(extra_context or {}) - context.update({'node': node, 'page': self, 'attributes': self.attributes_with_node(node), 'relationships': self.relationships_with_node(node)}) - return HttpResponse(self.template.django_template.render(RequestContext(request, context)), mimetype=self.template.mimetype) + context.update({'page': self, 'attributes': self.attributes, 'relationships': self.relationships}) + if node and request: + context.update({'node': node, 'attributes': self.attributes_with_node(node), 'relationships': self.relationships_with_node(node)}) + return self.template.django_template.render(RequestContext(request, context)) + return self.template.django_template.render(Context(context)) + + def render_to_response(self, node, request, path=None, subpath=None, extra_context=None): + return HttpResponse(self.render_to_string(node, request, path, subpath, extra_context), mimetype=self.template.mimetype) def __unicode__(self): return self.title diff --git a/utils.py b/utils.py index 340e9e4..efd9f98 100644 --- a/utils.py +++ b/utils.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.contenttypes.models import ContentType +from django.core.paginator import Paginator, EmptyPage class ContentTypeLimiter(object): @@ -62,3 +63,43 @@ def fattr(*args, **kwargs): setattr(function, key, kwargs[key]) return function return wrapper + + +def paginate(objects, per_page=None, page_number=1): + """ + Given a list of objects, return a (paginator, page, objects) tuple. + """ + try: + per_page = int(per_page) + except (TypeError, ValueError): + # Then either it wasn't set or it was set to an invalid value + paginator = page = None + + # There also shouldn't be pagination if the list is too short. Try count() + # first - good chance it's a queryset, where count is more efficient. + try: + if objects.count() <= per_page: + paginator = page = None + except AttributeError: + if len(objects) <= per_page: + paginator = page = None + + try: + return paginator, page, objects + except NameError: + pass + + paginator = Paginator(objects, per_page) + try: + page_number = int(page_number) + except: + page_number = 1 + + try: + page = paginator.page(page_number) + except EmptyPage: + page = None + else: + objects = page.object_list + + return paginator, page, objects