Source code for superdjango.ui.views.base

# Imports

from django.conf import settings
from django.http import Http404
from django.utils.translation import ugettext_lazy as _
import os
from superdjango.assets.library import JavaScript, StyleSheet
from superdjango.conf import SUPERDJANGO
from superdjango.views import BreadcrumbsMixin, MessageMixin
from .access import UIAccessMixin

# Exports

__all__ = (
    "UIBaseMixin",
)

# Classes


[docs]class UIBaseMixin(UIAccessMixin, BreadcrumbsMixin, MessageMixin): """Base class for UI views (except AJAX).""" 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.""" actions = None """An instance of :py:class:`superdjango.options.utils.Actions` containing the view-level actions for the current view.""" # base_template = SUPERDJANGO.BASE_TEMPLATE base_template = None """The base template used to render the view.""" raise_exception = settings.DEBUG """Indicates whether a processing exceptions should be raised or only logged.""" subtitle = None """The subtitle of the view page.""" template_name = None """The name of the template (which extends the ``base_template``) that is used to render the view. It omitted, an attempt is made to determine the template name automatically. See ``get_template_names()``. """ template_name_suffix = None """The template suffix used to automatically determine the template name. See ``get_template_names()``.""" title = None """The title of the view page.""" ui = None """The ModelUI instance that generated the view.""" # actions_label = None # permission_policy = None # 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 = _("The requested 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 """ # Allow the UI to override settings.py # noinspection PyUnresolvedReferences base = self.ui.get_base_template(self.request, self.get_verb()) return base or SUPERDJANGO.BASE_TEMPLATE
[docs] def get_breadcrumbs(self): """Get breadcrumbs for the model view.""" crumbs = super().get_breadcrumbs() # The "root" URL may be that of an app "above" this app. label, root_url = self.ui.get_root_url() if root_url is not None: crumbs.add(label, root_url) # If the index and root are different, also add the index of the current app. index_url = self.ui.get_index_url() if index_url != root_url: crumbs.add(self.ui.get_verbose_name_plural(), index_url) return crumbs
[docs] def get_context_data(self, *args, **kwargs): # It's possible (as with django-formtools) that this method is defined on an extended view. try: # noinspection PyArgumentList context = super().get_context_data(*args, **kwargs) except AttributeError: context = kwargs if self.actions is not None: context['actions_label'] = self.actions.label context['active_page'] = self.active_page context['active_subpage'] = self.active_subpage or "%s_%s" % (self.active_page, self.get_verb()) context['base_template'] = self.get_base_template() context['breadcrumbs'] = self.get_breadcrumbs() context['subtitle'] = self.get_subtitle() context['title'] = self.get_title() context['verbose_name'] = self.ui.get_verbose_name() context['verbose_name_plural'] = self.ui.get_verbose_name_plural() context['view'] = self context['view_css'] = self.get_css() context['view_js'] = self.get_js() return context
# noinspection PyMethodMayBeStatic
[docs] def get_css(self): """Get the URLs or markup of any CSS to be included in the view. :rtype: StyleSheet """ return StyleSheet()
# noinspection PyMethodMayBeStatic
[docs] def get_js(self): """Get the URLs or markup of any JavaScript to be included in the view. :rtype: JavaScript """ 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_name_suffix(self): """Get the suffix for the current view template. :rtype: str .. tip:: Extending classes should define the ``template_name_suffix``. The suffix should include an underscore for separation. For example, the suffix for a view for creating a new record would be ``_add``. The default behavior here is to return an empty string if ``template_name_suffix`` is not defined. """ if self.template_name_suffix is not None: return self.template_name_suffix return ""
[docs] def get_template_names(self): """Get the template names that may be used for rendering the response. :rtype: list[str] The possible names are generated like so: 1. If the child class defines a ``template_name``, this is always returned as the first element of the list. 2. This method first defines templates that may be defined by the local project in the form of ``{app_label}/{model_name_lower}{template_name_suffix}.html``. 3. Finally, the generic template is supplied for SuperDjango UI. """ templates = list() # This will be the first template that is checked, which means it takes priority over any other possible # template names. if self.template_name is not None: templates.append(self.template_name) # The default template name is based on the suffix, which may supplied by the extending class or by view # options. It takes second preference. suffix = self.get_template_name_suffix() if suffix is not None: file_name = "%s%s.html" % (self.ui.meta.model_name, suffix) templates.append(os.path.join(self.ui.meta.app_label, file_name)) # Include UI generic templates last. file_name = "model%s.html" % suffix templates.append(os.path.join("superdjango", "ui", file_name)) return templates
[docs] def get_title(self): """Get the page title. :rtype: str """ if self.title is not None: return self.title return self.ui.get_verbose_name()
[docs] def get_verb(self): """Get the verb/action associated with the view. :rtype: str .. important:: Child classes must implement this method. """ raise NotImplementedError()