Обтекание / декорирование функции в urls.py по сравнению с views.py - PullRequest
6 голосов
/ 27 апреля 2011

Итак, я довольно хорошо знаком с функциями упаковки в views.py.Итак, я написал декоратор для перенаправления на REDIRECT_URL по умолчанию, если пользователь вошел в систему (что-то вроде обратного login_required);это основано на том, как я делал представления в прошлом:

def not_logged_in(redirect_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    def decorator(view_func, *args, **kwargs):
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated():
                return view_func(*args, **kwargs)
            else:
                redirect_url = (request.REQUEST.get(redirect_field_name, redirect_url) or
                                settings.REDIRECT_URL)
                return HttpResponseRedirect(redirect_url)
        return wrapper
    return decorator

Однако я получаю следующую ошибку: 'function' object has no attribute 'status_code', которая вызвана тем, что MiddleWare ожидает HttpResponse.Когда я смотрю на значение для response, я вижу, что оно <function wrapper at 0x2b3a9922a500>.

Вот как я его называю в urls.py:

url(r'login/', 
     not_logged_in(auth_views.login), 
     {'authentication_form': LoginForm },
),

Ответы [ 3 ]

8 голосов
/ 27 апреля 2011

Вот моя реализация того же самого.

def logout_required(view):
    def f(request, *args, **kwargs):
        if request.user.is_anonymous():
            return view(request, *args, **kwargs)
        return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
    return f

В urls.py:

urlpatterns = patterns("",
    url(r"^login/", logout_required(login), {"template_name": "users/login.html"}, "login"),
    # ...

Надеюсь, это поможет (хотя и неуверенно).

1 голос
/ 27 апреля 2011

Способ реализации вашего декоратора, его параметризация и, следовательно, возможность вызова: вот почему у вас есть дополнительный уровень функций, который fizixx ошибочно говорит, что он не требуется. Сначала необходимо вызвать внешнюю оболочку, чтобы вернуть фактическую оформленную функцию. Так что-то вроде:

url(r'login/', 
 not_logged_in(auth_views.login)('/redirect/', 'redirect_field'), 
 {'authentication_form': LoginForm },
),
1 голос
/ 27 апреля 2011

Первым аргументом декоратора должна быть функция, которую нужно декорировать.

def not_logged_in(func, redirect_url=None, redirect_field_name=REDIRECT_FIELD_NAME):

Функция декоратора также не нужна.Возвращает функцию-обертку из not_logged_in.

...