Source code for pytoolbox.django.views.mixins

"""
Mix-ins for building your own views.
"""

import os

from django.contrib import messages
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.db import models
from django.shortcuts import redirect
from django.views.generic import base as generic

from pytoolbox import module
from pytoolbox.django.core import exceptions
from pytoolbox.django.forms import mixins as forms_mixins
from pytoolbox.django.models import utils

_all = module.All(globals())


[docs]class AddRequestToFormKwargsMixin(object): """Add the view request to the keywords arguments for instantiating the form."""
[docs] def get_form_kwargs(self, *args, **kwargs): kwargs = super().get_form_kwargs(*args, **kwargs) if self.should_add_request_to_form_kwargs(): kwargs.update({'request': self.request}) return kwargs
[docs] def should_add_request_to_form_kwargs(self): return issubclass(self.get_form_class(), forms_mixins.RequestMixin)
[docs]class BaseModelMultipleMixin(object):
[docs] def get_context_object_name(self, instance_list): """Get the name of the item to be used in the context.""" if self.context_object_name: return self.context_object_name elif hasattr(instance_list, 'model'): return f'{utils.get_base_model(instance_list.model)._meta.model_name}_list'
[docs]class BaseModelSingleMixin(object):
[docs] def get_context_object_name(self, instance): """Get the name to use for the instance.""" if self.context_object_name: return self.context_object_name elif isinstance(instance, models.Model): return utils.get_base_model(instance)._meta.model_name
[docs]class InitialMixin(object): """Add helpers to safely use the URL query string to fill a form with initial values.""" initials = {}
[docs] def get_initial(self): initial = super().get_initial() for name, default in self.initials.items(): self.set_inital(initial, name, default) return initial
[docs] def set_inital(self, initial, name, default): initial[name] = value = self.request.GET.get(name, default) return value
[docs] def set_initial_from_func(self, initial, name, default, func, msg_value, mgs_missing): value = self.request.GET.get(name, default) if value is not default: try: value = func(value) except ValueError: messages.error(self.request, f'{name} - {msg_value}.') return None except KeyError: messages.error(self.request, f'{name} - {mgs_missing}.') return None initial[name] = value return value
[docs] def set_initial_from_model(self, initial, name, default, model, msg_value, mgs_missing): value = self.request.GET.get(name, default) if value is not default: try: value = model.objects.for_user(self.request.user).get(pk=value) except ValueError: messages.error(self.request, f'{name} - {msg_value}.') return None except model.DoesNotExist: messages.error(self.request, f'{name} - {mgs_missing}.') return None initial[name] = value return value
[docs]class LoggedCookieMixin(object): """Add a "logged" cookie set to "True" if user is authenticated else to "False"."""
[docs] def post(self, *args, **kwargs): response = super().post(*args, **kwargs) logged = self.request.user.is_authenticated response.set_cookie('logged', logged if isinstance(logged, bool) else logged()) return response
[docs]class RedirectMixin(object): """Redirect to a page.""" redirect_view = None
[docs] def dispatch(self, request, *args, **kwargs): if self.redirect_view: return redirect(self.redirect_view) return super().dispatch(request, *args, **kwargs)
[docs]class TemplateResponseMixin(generic.TemplateResponseMixin): default_template_directory = 'default'
[docs] def get_template_names(self): return [self.template_name] if self.template_name else [ os.path.join(self.template_directory, self.action + '.html'), os.path.join(self.default_template_directory, self.action + '.html') ]
[docs]class ValidationErrorsMixin(object):
[docs] def form_valid(self, form): try: return super().form_valid(form) except ValidationError as ex: for field, error in exceptions.iter_validation_errors(ex): if field: form.add_error(field, error) else: self._handle_unknown_error(form, error) return self.form_invalid(form)
def _handle_unknown_error(self, form, error): form.add_error(NON_FIELD_ERRORS, error)
__all__ = _all.diff(globals())