Django Узнайте, прошел ли пользователь аутентификацию в пользовательском теге - PullRequest
0 голосов
/ 02 января 2011

Я пытаюсь создать пользовательский тег.Внутри этого пользовательского тега я хочу иметь некоторую логику, которая проверяет, вошел ли пользователь в систему, и затем соответствующим образом отображает тег.Вот что у меня есть:

def user_actions(context):
    request = template.Variable('request').resolve(context)
    return { 'auth': request['user'].is_athenticated() }

register.inclusion_tag('layout_elements/user_actions.html', takes_context=True)(user_actions)

Когда я запускаю это, я получаю эту ошибку:

Caught VariableDoesNotExist while rendering: Failed lookup for key [request] in u'[{}]'

Представление, которое отображает это, заканчивается так:

return render_to_response('start/home.html', {}, context_instance=RequestContext(request))

Почему тег не получает объект RequestContext вместо объекта Context?Как я могу получить тег для получения RequestContext вместо контекста?

EDIT:

Возможно ли получить RequestContext внутри пользовательского тега, мне все равно было бы интереснознать «правильный» или лучший способ определения состояния аутентификации пользователя из пользовательского тега.Если это невозможно, то, возможно, такая логика принадлежит другому?Где?

Ответы [ 4 ]

3 голосов
/ 03 января 2011

По умолчанию экземпляр django.template.Context используется в шаблонах рендеринга, но вы можете переопределить это в своем представлении, передав подкласс django.template.Context в качестве аргумента ключевого слова context_instance в render_to_response или создание экземпляра подкласса и передача его непосредственно Template.render.

Для удобства Django предоставляет полезный, заранее определенный подкласс Context: django.template.RequestContext. RequestContext ищет в вашем файле настроек параметр TEMPLATE_CONTEXT_PROCESSORS, который должен быть кортежем вызываемых объектов, каждый из которых должен возвращать словарь; RequestContext будет перебирать каждый вызываемый объект, вызывать его и добавлять пары ключ / значение из возвращенного словаря в контекст шаблона в качестве переменных. Проверьте эти ссылки для более подробного объяснения.

Чтобы добавить текущего пользователя в контекст шаблона, вам нужно django.core.context_processors.auth:

  1. Добавить контекст django.core.context_processors.auth процессор к вашему списку контекста процессоры в settings.py:

    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.auth',
        ... # Other context processors follow
    )
    
  2. Обеспечить представление, чем отображает шаблон, который вызывает Ваш пользовательский тег использует RequestContext:

    from django.template.context import RequestContext
    from django.shortcuts import render_to_response
    def my_view(request):
        # Do some stuff
        return render_to_response('templates/view.html', 
            context_instance=RequestContext(request))
    
  3. Использование RequestContext вызывает все определенные процессоры контекста в settings.TEMPLATE_CONTEXT_PROCESSORS, включая auth процессор контекста, который добавляет переменную контекста 'user' в контекст вашего шаблона.
    В вашем теге шаблона вы можете получить доступ к этой переменной через context['user']

    @register.inclusion_tag('templates/custom/tag.html', takes_context=True)
    def custom_tag(context):
        user = context['user']
        if user.is_authenticated():
            # Some stuff for the logged-in users
        else:
            # Stuff for anonymous users
    
1 голос
/ 06 января 2011

В итоге я просто передал тегу «user» параметр и использовал его, чтобы определить, был ли пользователь авторизован или нет.

1 голос
/ 02 января 2011

«Контекст» узла шаблона отличается от RequestContext. Context также является словарем, поэтому, если у него вообще есть пользователь, к нему можно получить доступ через context['user'].

Контекст узлов шаблона содержит информацию, которая помогает ему визуализироваться внутри шаблона, после некоторого чтения документов я не могу найти какой-либо способ доступа к RequestContext, который был бы связан с запросом через django.template.Context.


Более того, django.template.RequestContext расширяется от django.template.Context специально для обработки добавленного объекта запроса, который будет содержать пользователя. Поэтому неудивительно, что Context не будет иметь к нему доступа.

См. исходный код из Context для доказательства.

Как получить пользователя

После небольшого поиска я нашел метод django.template.resolve_variable, который можно использовать следующим образом:

from django.template import resolve_variable

user = resolve_variable('user', context)

Где context - контекст шаблона.

1 голос
/ 02 января 2011

Я не вижу, как ваше представление связано с тегом шаблона, потому что из того, что я знаю, система шаблонов его django, которая отображает тег, поэтому контекст является словарем, попробуйте это, надеюсь, это поможет

...