def permission_required(perm, fn=None, login_url=None, raise_exception=False, redirect_field_name=REDIRECT_FIELD_NAME):
def decorator(view_func):<EOL><INDENT>@wraps(view_func, assigned=available_attrs(view_func))<EOL>def _wrapped_view(request, *args, **kwargs):<EOL><INDENT>if isinstance(perm, six.string_types):<EOL><INDENT>perms = (perm,)<EOL><DEDENT>else:<EOL><INDENT>perms = perm<EOL><DEDENT>if callable(fn):<EOL><INDENT>obj = fn(request, *args, **kwargs)<EOL><DEDENT>else:  <EOL><INDENT>obj = fn<EOL><DEDENT>user = request.user<EOL>if not user.has_perms(perms, obj):<EOL><INDENT>if raise_exception:<EOL><INDENT>raise PermissionDenied()<EOL><DEDENT>else:<EOL><INDENT>return _redirect_to_login(request, view_func.__name__,<EOL>login_url, redirect_field_name)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return view_func(request, *args, **kwargs)<EOL><DEDENT><DEDENT>return _wrapped_view<EOL><DEDENT>return decorator<EOL>
View decorator that checks for the given permissions before allowing the
view to execute. Use it like this::

    from django.shortcuts import get_object_or_404
    from rules.contrib.views import permission_required
    from posts.models import Post

    def get_post_by_pk(request, post_id):
        return get_object_or_404(Post, pk=post_id)

    @permission_required('posts.change_post', fn=get_post_by_pk)
    def post_update(request, post_id):
        # ...

``perm`` is either a permission name as a string, or a list of permission
names.

``fn`` is an optional callback that receives the same arguments as those
passed to the decorated view and must return the object to check
permissions against. If omitted, the decorator behaves just like Django's
``permission_required`` decorator, i.e. checks for model-level permissions.

``raise_exception`` is a boolean specifying whether to raise a
``django.core.exceptions.PermissionDenied`` exception if the check fails.
You will most likely want to set this argument to ``True`` if you have
specified a custom 403 response handler in your urlconf. If ``False``,
the user will be redirected to the URL specified by ``login_url``.

``login_url`` is an optional custom URL to redirect the user to if
permissions check fails. If omitted or empty, ``settings.LOGIN_URL`` is
used.