Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination #137

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions bakery/tests/__init__.py
Expand Up @@ -268,6 +268,55 @@ def test_list_view(self):
self.assertTrue(os.path.exists(build_path))
os.remove(build_path)

def test_list_view_with_pagination(self):
v = views.BuildableListView(
queryset=[1, 2, 3],
template_name='listview.html',
build_path='foo.html',
)
v.paginate_by = 2
v.build_method()
page_default_path = os.path.join(settings.BUILD_DIR, 'foo.html')
page_1_path = os.path.join(settings.BUILD_DIR, 'page', '1', 'foo.html')
page_2_path = os.path.join(settings.BUILD_DIR, 'page', '2', 'foo.html')
self.assertTrue(os.path.exists(page_default_path))
self.assertTrue(os.path.exists(page_1_path))
self.assertTrue(os.path.exists(page_2_path))
os.remove(page_default_path)
os.remove(page_1_path)
os.remove(page_2_path)

v = views.BuildableListView(
queryset=[1, 2, 3, 4, 5, 6, 7, 8, 9],
template_name='listview.html',
build_path='foo.html',
)
v.paginate_by = 7
v.build_method()
page_default_path = os.path.join(settings.BUILD_DIR, 'foo.html')
page_1_path = os.path.join(settings.BUILD_DIR, 'page', '1', 'foo.html')
page_2_path = os.path.join(settings.BUILD_DIR, 'page', '2', 'foo.html')
self.assertTrue(os.path.exists(page_default_path))
self.assertTrue(os.path.exists(page_1_path))
self.assertTrue(os.path.exists(page_2_path))
os.remove(page_default_path)
os.remove(page_1_path)
os.remove(page_2_path)
v.paginate_by = 3
v.build_method()
page_default_path = os.path.join(settings.BUILD_DIR, 'foo.html')
page_1_path = os.path.join(settings.BUILD_DIR, 'page', '1', 'foo.html')
page_2_path = os.path.join(settings.BUILD_DIR, 'page', '2', 'foo.html')
page_3_path = os.path.join(settings.BUILD_DIR, 'page', '3', 'foo.html')
self.assertTrue(os.path.exists(page_default_path))
self.assertTrue(os.path.exists(page_1_path))
self.assertTrue(os.path.exists(page_2_path))
self.assertTrue(os.path.exists(page_3_path))
os.remove(page_default_path)
os.remove(page_1_path)
os.remove(page_2_path)
os.remove(page_3_path)

def test_detail_view(self):
v = views.BuildableDetailView(
queryset=MockObject.objects.all(),
Expand Down
55 changes: 50 additions & 5 deletions bakery/views/list.py
Expand Up @@ -3,6 +3,7 @@
for building flat files.
"""
import logging
import math
from fs import path
from .base import BuildableMixin
from django.conf import settings
Expand All @@ -29,16 +30,60 @@ class BuildableListView(ListView, BuildableMixin):
template_name:
The name of the template you would like Django to render. You need
to override this if you don't want to rely on the Django defaults.

Pagination is handled like a django ListView, and templates should be
designed in the same way.
When pagination is enabled the default build locations for the first page
are: build_folder/build_path and /build_folder/build_page_name/1/build_path,
with other pages only built in:
/build_folder/build_page_name/<page_number>/build_path
"""
build_folder = ''
build_page_name = "page"
build_path = 'index.html'

@property
def build_method(self):
return self.build_queryset
if self.get_paginate_by(self.queryset):
return self.build_pagination
else:
return self.build_queryset

def build_pagination(self):
"""
If pagination is enabled, build the queryset for each page.
"""

number_of_pages = int(math.ceil(len(self.queryset) /
float(self.paginate_by)))
if not hasattr(self, "kwargs"):
self.kwargs = {}
for page in range(0, number_of_pages + 1):
self.kwargs['page'] = page
self.build_queryset()

def get_page_build_path(self):
"""
Create the path to build each page in pagination
Defaults to building in:
<build_folder>/<build_page_name>/<page>/<build_path>
The current page is held in self.kwargs['page']
"""
build_path = path.join(self.build_folder, self.build_page_name,
str(self.kwargs['page']), self.build_path)
return build_path

def get_build_path(self):
build_path = ''
if self.get_paginate_by(self.queryset) and self.kwargs['page']:
build_path = self.get_page_build_path()
else:
build_path = path.join(self.build_folder, self.build_path)
return build_path

def build_queryset(self):
logger.debug("Building %s" % self.build_path)
self.request = self.create_request(self.build_path)
self.prep_directory(self.build_path)
target_path = path.join(settings.BUILD_DIR, self.build_path)
logger.debug("Building %s" % self.get_build_path())
self.request = self.create_request(self.get_build_path())
self.prep_directory(self.get_build_path())
target_path = path.join(settings.BUILD_DIR, self.get_build_path())
self.build_file(target_path, self.get_content())
25 changes: 25 additions & 0 deletions docs/buildableviews.rst
Expand Up @@ -49,6 +49,10 @@ BuildableListView
Render and builds a page about a list of objects. Extended from Django's
generic `ListView <https://docs.djangoproject.com/en/dev/ref/class-based-views/generic-display/#django.views.generic.list.ListView>`_.
The base class has a number of options not documented here you should consult.
Pagination is handled like a django ListView, and templates should be
designed in the same way.
When pagination is enabled the default build locations for the first page are: build_folder/build_path and /build_folder/build_page_name/1/build_path, with other pages only built in:
/build_folder/build_page_name/<page_number>/build_path

.. attribute:: model

Expand All @@ -63,6 +67,19 @@ BuildableListView
if this attribute is not defined the ``model`` attribute must be
defined.

.. attribute:: build_folder

The target location of the flat file in the ``BUILD_DIR``.
Optional. The default is blank, would place the flat file
at the site's root. Defining it as ``foo/`` would place
the flat file inside a subdirectory foo/.

.. attribute:: build_page_name

The target location of the flat file in the ``BUILD_DIR``.
Optional. The default is ``page``, would place the page file
in /page/1/<build_path>, /page/2/<build_path>.

.. attribute:: build_path

The target location of the flat file in the ``BUILD_DIR``.
Expand All @@ -80,6 +97,14 @@ BuildableListView

An alias to the ``build_queryset`` method used by the :doc:`management commands </managementcommands>`

.. py:method:: get_page_build_path()

Create the path to build each page in pagination
Defaults to building in:
<build_folder>/<build_page_name>/<page>/<build_path>
The current page is held in self.kwargs['page']


.. py:method:: build_queryset()

Writes the rendered template's HTML to a flat file. Only override this if you know what you're doing.
Expand Down