code: def permission_required(perm, queryset=None,
                          login_url=None, raise_exception=False):
      
      def wrapper(view_func):
          @wraps(view_func, assigned=available_attrs(view_func))
          def inner(request, *args, **kwargs):
              _kwargs = copy.copy(kwargs)
              # overwrite queryset if specified
              if queryset:
                  _kwargs['queryset'] = queryset
  
              # get object from view
              if 'date_field' in _kwargs:
                  fn = get_object_from_date_based_view
              else:
                  fn = get_object_from_list_detail_view
              if fn.validate(request, *args, **_kwargs):
                  obj = fn(request, *args, **_kwargs)
              else:
                  # required arguments is not passed
                  obj = None
  
              if not request.user.has_perm(perm, obj=obj):
                  if raise_exception:
                      raise PermissionDenied
                  else:
                      return redirect_to_login(request, login_url)
              return view_func(request, *args, **_kwargs)
          return inner
      return wrapper
docs: Permission check decorator for function-base generic view
  
      This decorator works as function decorator
  
      Parameters
      ----------
      perm : string
          A permission string
      queryset : queryset or model
          A queryset or model for finding object.
          With classbased generic view, ``None`` for using view default queryset.
          When the view does not define ``get_queryset``, ``queryset``,
          ``get_object``, or ``object`` then ``obj=None`` is used to check
          permission.
          With functional generic view, ``None`` for using passed queryset.
          When non queryset was passed then ``obj=None`` is used to check
          permission.
  
      Examples
      --------
      >>> @permission_required('auth.change_user')
      >>> def update_auth_user(request, *args, **kwargs):
      ...     pass