# Imports
from django.views.generic import RedirectView as DjangoRedirectView
from django.utils.translation import ugettext_lazy as _
from superdjango.exceptions import IMustBeMissingSomething
from .messages import MessageMixin
from .templates import TemplateView
# Exports
__all__ = (
"CallbackRedirectView",
"CountRedirectView",
"DelayedRedirectView",
"RedirectView",
)
# Views
[docs]class CallbackRedirectView(DjangoRedirectView):
"""Allows the specification of a redirect callback when the view is created."""
redirect_callback = None
"""A callable that is used to issue the redirect. It should accept a request argument and return an
``HTTPResponseRedirect``.
"""
[docs] def get_redirect_callback(self):
"""Get the redirect callback function."""
if self.redirect_callback is None or not callable(self.redirect_callback):
raise IMustBeMissingSomething(self.__class__.__name__, "redirect_callback", "get_redirect_callback")
return self.redirect_callback
[docs] def get_redirect_url(self, *args, **kwargs):
"""Attempt to issue a redirect using the provided callback."""
callback = self.get_redirect_callback()
return callback(self.request)
[docs]class CountRedirectView(MessageMixin, DjangoRedirectView):
"""Logs a "hit" before redirecting."""
counter_callback = None
"""A callable that may be used to the activity. If defined, the callback is passed the request instance and redirect
URL, as in ``callback(request, url)``.
"""
[docs] def get_counter_callback(self):
"""Get the callable, if any, that may be used to record model activity.
.. tip::
No error is raised if the ``counter_callback`` does not exist or is not callable.
"""
if self.counter_callback is not None and callable(self.counter_callback):
return self.counter_callback
return None
[docs] def get_redirect_url(self, *args, **kwargs):
"""Execute callback before returning the redirect URL."""
redirect_url = super().get_redirect_url(*args, **kwargs)
callback = self.get_counter_callback()
if callback is not None:
callback(self.request, redirect_url)
return redirect_url
[docs]class DelayedRedirectView(MessageMixin, TemplateView):
"""Redirect the user after a delay."""
countdown_enabled = True
"""Indicates whether a countdown should be displayed."""
delayed_seconds = 5
"""The number of seconds to wait before issuing the redirect."""
redirect_url = None
"""The URL to which the user should be redirected."""
template_name = "superdjango/views/delayed_redirect.html"
"""The default template to use for the redirect page."""
[docs] def get_context_data(self, **kwargs):
"""Add delayed redirect variables to the context.
- ``countdown_enabled``
- ``delayed_seconds``
- ``redirect_url``
"""
context = super().get_context_data(**kwargs)
context['countdown_enabled'] = self.countdown_enabled
context['delayed_seconds'] = self.delayed_seconds
context['redirect_url'] = self.get_redirect_url()
return context
[docs] def get_redirect_url(self):
"""Get the URL to which the user should be redirected.
:rtype: str
"""
if self.redirect_url is not None:
return self.redirect_url
raise IMustBeMissingSomething(self.__class__.__name__, "redirect_url", "get_redirect_url")
[docs] def get_title(self):
"""Get the default title."""
if self.title is not None:
return self.title
return _("Redirect")
[docs]class RedirectView(MessageMixin, DjangoRedirectView):
"""A redirect view which incorporates message functionality."""
pass