# Imports
from django.http import Http404
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import View as GenericView
from superdjango.assets.library import JavaScript, StyleSheet
from superdjango.conf import SUPERDJANGO
from superdjango.exceptions import IMustBeMissingSomething
__all__ = (
"BaseView",
"GenericView",
)
# Views
[docs]class BaseView(GenericView):
"""A mixin for establishing core functionality for all views."""
active_page = None
"""The name of the active page that may be used to identify the current view within a menu."""
active_subpage = None
"""The name of the active subpage that may be used to identify the current view within a submenu."""
base_template_name = SUPERDJANGO.BASE_TEMPLATE
"""The base template to extend."""
css = None
"""A list of CSS markup elements that maybe added to the output. See ``get_css()``."""
js = None
"""A list of JavaScript markup elements that maybe added to the output. See ``get_js()``."""
raise_exception = False
"""Indicates whether exceptions should be raised during processing or mitigated, if possible."""
subtitle = None
"""The subtitle of the page."""
template_name = None
"""The name of the template to use for rendering the view."""
title = None
"""The title of the page."""
# noinspection PyMethodMayBeStatic
[docs] def dispatch_not_found(self, message=None):
"""Dispatch a 404 (page not found) error. By default, this just raises an ``Http404``.
:param message: The 404 message.
"""
if message is None:
message = _("This page could not be located.")
raise Http404(message)
[docs] def get_base_template(self):
"""Get the name of the base template to use for rendering the view.
:rtype: str
"""
if self.base_template_name is not None:
return self.base_template_name
raise IMustBeMissingSomething(self.__class__.__name__, "base_template_name", "get_base_template")
[docs] def get_css(self):
"""Get the URLs or markup of any CSS to be included in the view.
:rtype: Style
"""
if self.css is not None:
return self.css
return StyleSheet()
[docs] def get_context_data(self, **kwargs):
"""Uses keyword arguments as the base context and adds the current view instance as ``view``.
:rtype: dict
The following variables are added to the context:
- ``active_page``: The identifier for the active menu item.
- ``active_subpage``: The identifier for the active sub-menu item.
- ``base_template``: The template to extend, i.e. ``{% extends base_template %}``.
- ``subtitle``: The subtitle of the page.
- ``title``: The title of the page.
- ``view``: The current view instance.
- ``view_css``: A Style instance.
- ``view_js``: A JavaScript instance.
"""
kwargs['active_page'] = self.active_page
kwargs['active_subpage'] = self.active_subpage
kwargs['base_template'] = self.get_base_template()
kwargs['subtitle'] = self.get_subtitle()
kwargs['title'] = self.get_title()
kwargs['view'] = self
kwargs['view_css'] = self.get_css()
kwargs['view_js'] = self.get_js()
return kwargs
[docs] def get_js(self):
"""Get the URLs or markup of any JavaScript to be included in the view.
:rtype: JavaScript
"""
if self.js is not None:
return self.js
return JavaScript()
[docs] def get_subtitle(self):
"""Get the page subtitle.
:rtype: str
"""
if self.subtitle is not None:
return self.subtitle
return ""
[docs] def get_template_names(self):
"""Get the name of the template used to render the response.
:rtype: list[str]
"""
if self.template_name is not None:
return [self.template_name]
raise IMustBeMissingSomething(self.__class__.__name__, "template_name", "get_template_names")
[docs] def get_title(self):
"""Get the page title.
:rtype: str
"""
if self.title is not None:
return self.title
return ""
[docs] def render_to_response(self, context):
"""Render the current context.
:param context: The context variables to use for rendering.
:rtype: TemplateResponse
"""
# noinspection PyUnresolvedReferences
return TemplateResponse(self.request, self.get_template_names(), context=context)