Source code for django_crucrudile.routes.mixins.model

"""This module contains :class:`ModelMixin`, a route mixin that can be used
to bind a model to a route, and use it when computing route metadata.

"""


[docs]class ModelMixin: """Route mixin that requires a model to be set either on the class (:attr:`model` attribute), or to be passed in :func:`__init__`, and provides the URL name and URL part using the model metadata. .. warning:: This mixin does not make :class:`django_crucrudile.routes.base.BaseRoute` a concrete class ! .. inheritance-diagram:: ModelMixin """ model = None """ :attribute model: Model to use on the Route :type model: :class:`django.db.models.Model` """ prefix_url_part = False """ :attribute prefix_url_part: Prefix the URL part with the model (ex: ``/model/<url_part>``) :type prefix_url_part: bool """
[docs] def __init__(self, *args, model=None, **kwargs): """Initialize ModelRoute, check that model is defined at class-level or passed as argument. :argument model: See :attr:`model` :raises ValueError: ``model`` argument is None, and no model defined in :attr:`model` """ if model is not None: self.model = model elif self.model is None: # pragma: no cover raise ValueError( "No ``model`` argument provided to __init__" ", and no model defined as class attribute (in {})" "".format(self) ) super().__init__(*args, **kwargs)
@property
[docs] def model_url_name(self): """Return the model name to be used when building the URL name :returns: URL name from model name, using Django internals :rtype: str >>> from django_crucrudile.routes.base import BaseRoute >>> from mock import Mock >>> >>> class ModelRoute(ModelMixin, BaseRoute): ... def get_callback(self): ... pass >>> >>> model = Mock() >>> model._meta.model_name = 'testmodel' >>> route = ModelRoute(model=model, name='routename') >>> >>> route.model_url_name 'testmodel' """ return self.model._meta.model_name
@property
[docs] def model_url_part(self): """Return the model name to be used when building the URL part :returns: URL part from the URL name (:func:`model_url_name`) :rtype: str >>> from django_crucrudile.routes.base import BaseRoute >>> from mock import Mock >>> >>> model = Mock() >>> model._meta.model_name = 'testmodel' >>> route = ModelMixin(model=model) >>> >>> route.model_url_part 'testmodel' """ return self.model._meta.model_name
[docs] def get_url_specs(self): """Return URL specs where the model URL name is appended to the prefix part list if needed :returns: URL specifications :rtype: iterable of 3-tuple >>> from django_crucrudile.routes.base import BaseRoute >>> from mock import Mock >>> >>> class ModelRoute(ModelMixin, BaseRoute): ... def get_callback(self): ... pass >>> >>> model = Mock() >>> model._meta.model_name = 'testmodel' >>> route = ModelRoute(model=model, name='routename') >>> >>> list(route.get_url_specs()) [([], ['routename'], [])] With :attr:`prefix_url_part` set to ``True`` : >>> from django_crucrudile.routes.base import BaseRoute >>> from mock import Mock >>> >>> class PrefixModelRoute(ModelMixin, BaseRoute): ... def get_callback(self): ... pass ... prefix_url_part = True >>> >>> model = Mock() >>> model._meta.model_name = 'testmodel' >>> route = PrefixModelRoute( ... model=model, name='routename', ... ) >>> >>> list(route.get_url_specs()) ... # doctest: +NORMALIZE_WHITESPACE [(['testmodel'], ['routename'], [])] """ for prefix, name, suffix in super().get_url_specs(): if self.prefix_url_part: yield prefix + [self.model_url_part], name, suffix else: yield prefix, name, suffix
[docs] def get_url_name(self): """Return the URL name built :func:`model_url_name` and :attr:`Route.name`. :returns: compiled URL name :rtype: str >>> from django_crucrudile.routes.base import BaseRoute >>> from mock import Mock >>> >>> class ModelRoute(ModelMixin, BaseRoute): ... def get_callback(self): ... pass >>> >>> model = Mock() >>> model._meta.model_name = 'testmodel' >>> route = ModelRoute( ... model=model, name='routename', ... ) >>> >>> route.get_url_name() 'testmodel-routename' """ return "{}-{}".format(self.model_url_name, self.name)