Source code for jmb.core.views.odt
# -*- coding: utf-8 -*-
"""
.. _class-based-odt:
OdtTemplateView
================
these views are Class Views implementation that return a response to serve
``pdf``, ``odt`` or ``ods`` files. It's pretty easy to create a view that
is :ref:`not class based <appypod>` so I'm not stating this is really needed,
but you may prefere this approach.
variants
--------
:|PdfTemplateView|: return a Pdf object
:|OdtTemplateView|: return a Odt object
:|OdsTemplateView|: return a Ods object
examples
--------
A simple example:
.. code-block:: python
class MyPdfTemplateView(PdfTemplateView):
template_name = app_label/template.odt
class MyOdtTemplateView(PdfTemplateView):
template_name = app_label/template.odt
urlpatterns = patterns('',
url(r'^pdf/(?P<slug>[a-zA-Z-]+)/$', MyPdfTemplateView.as_view(), name='pdf_detail')
url(r'^odt/(?P<slug>[a-zA-Z-]+)/$', MyOdtTemplateView.as_view(), name='odt_detail')
)
debug
-----
Since it's pretty standard to create the .odt template via try and fix
you can create a method named debug_template to step into and just lanch
creation of the file w/o recreating the context::
def debug_template(self, template, context):
template.save_as('/tmp/output.odt', context=context)
import ipdb; ipdb.set_trace()
API
---
.. autoclass:: OdtTemplateResponseMixin
:members:
.. autoclass:: PdfTemplateView
:members:
.. autoclass:: OdtTemplateView
.. autoclass:: OdsTemplateView
.. |PdfTemplateView| replace:: :class:`PdfTemplateView`
.. |OdtTemplateView| replace:: :class:`OdtTemplateView`
.. |OdsTemplateView| replace:: :class:`OdsTemplateView`
"""
from __future__ import unicode_literals
import os
import copy
from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
from django.http import HttpResponse
from jmb.core.utils.appypod import AppyPodTemplate
[docs]class OdtTemplateResponseMixin(TemplateResponseMixin):
"""
A mixin class that implements Odt rendering and Django response construction.
"""
#: Type of the output; used to set content-type appropriately
output_type = None
#: forces use of openoffice even if the output is and odt file (passed to appyod render)
forceOoCall = False
#: Boolean. Add 'attachment;' to Content-Disposition so that a popup queringwhat to do
#: is triggerend rather that in-browser representation
attachment = False
@property
def output_filename(self):
return "%s.%s" % (os.path.splitext(os.path.basename(self.template_name))[0],
self.output_type)
[docs] def get_template_names(self):
"""
Return the template names (string or list)
"""
return self.template_name
[docs] def get_output_filename(self):
"""
Returns :attr:`pdf_filename` value by default.
If left blank the browser will display the Odt inline.
Otherwise it will pop up the "Save as.." dialog.
:rtype: :func:`str`
"""
return self.output_filename
def get_mime_type(self, output_type='pdf'):
return {
'pdf': 'application/pdf',
'odt': 'application/vnd.oasis.opendocument.text',
'ods': 'application/vnd.oasis.opendocument.spreadsheet',
}[output_type]
[docs] def get_response(self, context, **response_kwargs):
"""
Renders Odt document and prepares response.
:arg context: the context
:arg response_kwargs: received from :meth:`render_to_response`
:returns: a rendered template (.pdf, .odt or .ods document)
"""
template = AppyPodTemplate(self.get_template_names())
try:
self.debug_template(template, context)
except AttributeError:
pass
return template.render(
file_type=self.output_type,
context=context,
forceOoCall=self.forceOoCall
)
[docs] def render_to_response(self, context, **response_kwargs):
"""
Return a rendered template as an HttpRespons
:rtype: :class:`django.http.HttpResponse`
"""
response = HttpResponse(
self.get_response(context, **response_kwargs),
content_type=self.get_mime_type(self.output_type),
)
output_filename = self.get_output_filename()
if output_filename:
response['Content-Disposition'] = '%sfilename="%s"' % (
self.attachment and 'attachment; ' or '', output_filename
)
return response
[docs]class PdfTemplateView(OdtTemplateResponseMixin, ContextMixin, View):
"""
Concrete view for serving Pdf files.
"""
output_type = 'pdf'
[docs] def get(self, request, *args, **kwargs):
"""
Handles GET request and returns HTTP response.
"""
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
[docs]class OdtTemplateView(PdfTemplateView):
"""
Concrete view for serving Odt files.
"""
output_type = 'odt'
[docs]class OdsTemplateView(PdfTemplateView):
"""
Concrete view for serving Ods files.
"""
output_type = 'ods'