Подтвердить что ты не робот

Login_required decorator на представлениях ajax для возврата 401 вместо 302

При написании некоторых представлений для ответа на запросы ajax я нахожу несколько странным, что декоратор login_required всегда возвращает код состояния 302 для не прошедших проверку подлинности пользователей. Поскольку эти взгляды представляют собой ajax-взгляды, это кажется несколько неуместным. Я не хочу, чтобы пользователь регистрировался в таком случае, но я хочу, чтобы Django сообщал клиенту, что для доступа к такому представлению требуется аутентификация (401 должен быть правильным кодом состояния, я думаю).

Чтобы достичь этого, я начал писать свой собственный декоратор login_required_ajax, но почему-то это выходит за рамки моих навыков. Это то, к чему я придумал:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)

        if function is None:
            return _decorator
        else:
            return _decorator(function)

При использовании этого декоратора в представлении я получаю исключение ViewDoesNotExist, как только я пытаюсь получить доступ к любой странице на сайте.

Сначала я подумал, что проблема может быть прямым возвратом HttpResponse, когда пользователь не аутентифицирован, потому что объект ответа не является вызываемым. Но тогда декоратор должен работать, пока я не пытаюсь получить доступ к рассматриваемому виду, не так ли? И если это действительно так, как я могу написать декоратор, который возвращает HttpResponse с кодом состояния 401?

4b9b3361

Ответ 1

Это довольно хорошая попытка. Вот несколько проблем, которые я заметил:

  • Функция _decorator должна возвращать _wrapped_view.
  • Отступ для вашего блока if function is None немного выключен - функция login_required_ajax должна вернуть оформленную функцию.

Здесь декоратор с этими изменениями сделал:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)
        return _wrapped_view

    if function is None:
        return _decorator
    else:
        return _decorator(function)