Run the given method prior to the decorated view.

    If you return anything besides ``None`` from the given method,
    its return values will replace the arguments of the decorated
    view.

    If you return an instance of ``HttpResponse`` from the given method,
    Respite will return it immediately without delegating the request to the
    decorated view.

    Example usage::

        class ArticleViews(Views):

            @before('_load')
            def show(self, request, article):
                return self._render(
                    request = request,
                    template = 'show',
                    context = {
                        'article': article
                    }
                )

            def _load(self, request, id):
                try:
                    return request, Article.objects.get(id=id)
                except Article.DoesNotExist:
                    return self._error(request, 404, message='The article could not be found.')

    :param method: A string describing a class method.

def before(method_name):
    """
    Run the given method prior to the decorated view.

    If you return anything besides ``None`` from the given method,
    its return values will replace the arguments of the decorated
    view.

    If you return an instance of ``HttpResponse`` from the given method,
    Respite will return it immediately without delegating the request to the
    decorated view.

    Example usage::

        class ArticleViews(Views):

            @before('_load')
            def show(self, request, article):
                return self._render(
                    request = request,
                    template = 'show',
                    context = {
                        'article': article
                    }
                )

            def _load(self, request, id):
                try:
                    return request, Article.objects.get(id=id)
                except Article.DoesNotExist:
                    return self._error(request, 404, message='The article could not be found.')

    :param method: A string describing a class method.
    """
    def decorator(function):
        @wraps(function)
        def wrapper(self, *args, **kwargs):
            returns = getattr(self, method_name)(*args, **kwargs)

            if returns is None:
                return function(self, *args, **kwargs)
            else:
                if isinstance(returns, HttpResponse):
                    return returns
                else:
                    return function(self, *returns)
        return wrapper
    return decorator