繁体   English   中英

python/django - 分配给装饰器中的全局变量

[英]python/django - assigning to global variable in decorator

我使用线程局部变量来实现基于用户的主题。 首先我写了一个中间件并且没有任何问题。 现在我将它转换为装饰器并且遇到了一个令人尴尬的问题。 这是简化的代码:

# 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 属性不存在的抱怨。 它去哪儿了? 很可能我错过了与闭包中的范围相关的一些东西,但不知道是什么。

您的代码对我有用,但some_view是 some_view 在get_theme之前调用。

每次您修改项目目录中的文件时,开发服务器都会终止您的进程并重新启动一个新进程。 完成后,您的线程数据当然会丢失。 如果您看到"Validating models..."消息,则您的线程数据已经丢失。

更改 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 object 以查看他们将主题设置为什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM