python / django - присвоение глобальной переменной в декораторе - PullRequest
2 голосов
/ 27 мая 2011

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

# views.py

_thread_locals = threading.local()

def foo_decorator(f):
    def _wrapper(*args, **kwargs):
        global _thread_locals
        _thread_locals.bar = kwargs['bar']
        return f(*args, **kwargs)
    return wraps(f)(_wrapper)

@foo_decorator
def some_view(request, bar):
    # Stuff here
    # Here _thread_locals.bar exists

# This is called by the template loader:
def get_theme():
    return _thread_locals.bar # Error

Когда я вызываю get_theme, я получаю жалобу на то, что атрибут bar не существует.Куда это делось?Скорее всего, я упускаю что-то, связанное с ограничением в замыканиях, но не могу понять, что.

Ответы [ 2 ]

0 голосов
/ 31 августа 2011

Изменение загрузчика шаблонов django для поддержки темы - это то, что я сделал.

`def load_template_for_user(user, template_name):
    """
    Loads a template for a particular user from a theme.
    This is used in the generic baseviews and also in the theme template tags

1. First try and load the template with the users theme.
2. Second if that doesn't exist, try and load the template from the default theme
3. Send the template name to the loader to see if we can catch it.
4. With the order of the template loaders, the template loader above will try and
   load from the Database.
   This will happen if the user tries to use {% extends %} or {% include %} tags
 """

    _theme = get_theme_for_user(user)
    _theme_template_name = "" + _theme.name + "/templates/" + template_name

    # Get the default theme
    _default_theme = get_default_theme()
    _default_theme_template_name = "" + _default_theme.name + "/templates/" + template_name

    _templates=[_theme_template_name, _default_theme_template_name, template_name]

    try:
        return loader.select_template(_templates)
    except TemplateDoesNotExist, e:
        log.error("Couldn't load template %s" % template_name)
        raise
    except Exception, e:
        log.error("Couldn't load template, generic Exception %s" % e)
        raise

`

Очевидно, что есть некоторый код, который вы не можете видеть, но он в основном выглядитна моделях, чтобы увидеть, что такое default_theme, и get_theme_for_user смотрит на объект UserProfile, чтобы увидеть, для чего они установили свою тему.

0 голосов
/ 02 июня 2011

Ваш код работает для меня, но только если some_view вызывается раньше get_theme.

Devserver убивает ваш процесс и перезапускает новый каждый раз, когда вы изменяете файл в каталоге вашего проекта. Ваши данные потока, конечно, теряются, когда это сделано Если вы видите сообщение "Validating models...", ваши данные в потоке уже потеряны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...