Source code for django_crucrudile.routes.mixins.view

"""This module contains a route mixin, :class:`ViewMixin`, that
implements :class:`django_crucrudile.routes.base.BaseRoute`.

"""


[docs]class ViewMixin: """Route mixin, implements :class:`django_crucrudile.routes.base.BaseRoute`, requires a view class to be set either on the class (:attr:`callback` attribute), or to be passed in :func:`__init__`. The view class will be used to get the callback to give to the URL pattern. .. note:: This mixin makes the class concrete, as it implements the :func:`django_crucrudile.routes.base.BaseRoute.get_callback` abstract function. .. inheritance-diagram:: ViewMixin >>> class TestView: ... pass >>> >>> route = ViewMixin(TestView) >>> >>> route.view_class.__name__ 'TestView' >>> route.name 'test' With :attr:`auto_url_name_from_view` set to ``False`` : >>> class TestView: ... pass >>> >>> route = ViewMixin(TestView, auto_url_name_from_view=False) >>> >>> route.view_class.__name__ 'TestView' >>> >>> # Because :class:`ViewMixin` does not even set >>> # :attr:`django_crucrudile.routes.base.BaseRoute.name` if >>> # :attr:`auto_url_name_from_view` is ``False``, this will >>> # raise an attribute error : >>> route.name Traceback (most recent call last): ... AttributeError: 'ViewMixin' object has no attribute 'name' """ view_class = None """ :attribute view_class: View class that will be used to get the callback to pass to the URL pattern :type view_class: subclass of :class:`django.views.generic.view` """ auto_url_name_from_view = True """ :attribute auto_url_name_from_view: Automatically set route name using view class name (lower casing it, and stripping it of ``View``) :type auto_url_name_from_view: bool """
[docs] def __init__(self, view_class=None, name=None, auto_url_name_from_view=None, *args, **kwargs): """Initialize ViewRoute, check that view_class is defined at class-level or passed as argument. :argument view_class: See :attr:`view_class` :argument auto_url_name_from_view: See :attr:`auto_url_name_from_view` .. seealso:: For doctests that use this member, see :class:`ViewMixin` :raises ValueError: if both ``view_class`` and :attr:`view_class` are None """ if view_class is not None: self.view_class = view_class if auto_url_name_from_view is not None: self.auto_url_name_from_view = auto_url_name_from_view elif self.view_class is None: # pragma: no cover raise ValueError( "No ``view_class`` argument provided to __init__" ", and no view_class defined as class attribute (in {})" "".format(self) ) if name is not None: kwargs['name'] = name elif self.auto_url_name_from_view: view_name = self.view_class.__name__ if view_name.endswith('View'): view_name = view_name[:-4] self.name = view_name.lower() super().__init__(**kwargs)
[docs] def get_callback(self): """Return callback using :func:`django.generic.views.View.as_view`, getting arguments from :func:`get_view_kwargs`. Calls :func:`View.as_view` on view class, with kwargs from :func:`get_view_kwargs`, to get callback to use in URL pattern. :returns: Callback to use in URL pattern :rtype: callable >>> from mock import Mock >>> callback = Mock() >>> mock_view = Mock() >>> mock_view.__name__ = 'MockView' >>> mock_view.as_view = lambda: callback >>> >>> route = ViewMixin(view_class=mock_view) >>> route.get_callback() is callback True """ return self.view_class.as_view( **self.get_view_kwargs() )
[docs] def get_view_kwargs(self): """Return arguments to use when calling the callback builder. :returns: Keyword arguments :rtype: dict """ return {}
@classmethod
[docs] def make_for_view(cls, view_class, **kwargs): """Return a subclass of this class, setting the ``view_class`` argument at class-level. Also sets the :attr:`django_crucrudile.routes.base.BaseRoute.name` attribute using the view class name. This is useful when combined with :func:`django_crucrudile.entities.store.EntityStore.register_class`, as it only accepts classes (in opposition to :func:`django_crucrudile.entities.store.EntityStore.register`). :argument view_class: View class to set on the resulting class :type view_class: subclass of :class:`django.views.generic.view` :returns: New class, with :attr:`view_class` attribute set to ``view_class`` argument. >>> class TestView: ... pass >>> >>> route_class = ViewMixin.make_for_view(TestView) >>> >>> route_class.__name__ 'TestRoute' >>> route_class.view_class.__name__ 'TestView' """ view_name = view_class.__name__ if view_name.endswith('View'): view_name = view_name[:-4] route_name = "{}Route".format(view_name) kwargs['view_class'] = view_class return type( route_name, (cls,), kwargs )