【问题标题】:In Django, is it possible to access the current user session from within a custom tag?在 Django 中,是否可以从自定义标签中访问当前用户会话?
【发布时间】:2010-09-25 00:21:26
【问题描述】:

我正在 Django 中编写一个自定义标记,该标记应输出存储在用户会话中的值,但我找不到从自定义标记函数中访问会话对象的方法。有没有办法做到这一点,而无需手动将会话对象分配给上下文变量?

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    您应该能够在 settings.py 文件中添加请求上下文处理器:

    TEMPLATE_CONTEXT_PROCESSORS = ("django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    'django.core.context_processors.request',)
    

    这将与当前答案执行相同的操作,而无需添加自定义文件。

    【讨论】:

    • 我建议将答案切换到这种方法,它更干净。
    • 我已经有了那个预处理器,但肯定忽略了会话属性。哦!谢谢。
    • 我已经添加了这个,但是如何从模板中访问请求? context.session 不存在。
    • @Wouter 会话可在request.session
    【解决方案2】:

    Sebastian 无意冒犯,因为这似乎是一个有用的 hack,但奇怪的是,12 月 24 日,在一篇关于在 Admin 中访问用户数据的博客文章中,Django 的发布经理 James Bennett 这么说 @ 987654321@:

    一个重要的免责声明:这些类型的功能有很多潜在的用途。他们中的许多人都是错误的和愚蠢的,你不应该尝试它们。 ... 此外,您偶尔会看到有人建议这些功能可以通过所谓的“threadlocal hack”获得;这基本上涉及将 request.user 粘贴到一种神奇的全局可用变量中,如果您不知道自己在做什么,那么使用它是一件非常糟糕的事情。即使您确实知道自己在做什么,这通常也是一件非常糟糕的事情,因为您可能只是因为懒惰并且不想确保正确传递信息而这样做。因此,如果您看到有人建议您使用“threadlocal”执行此操作,请忽略该人。

    并不是说您应该忽略 Sebastian,但可能值得追求其他途径而不是使用不是最佳实践的 threadlocal。

    【讨论】:

    • 这是很重要的一点,但我必须指出,也许 Bennett 先生关于程序员可能“懒惰并且不喜欢确保正确传递信息”的评论并不完全公平。 Django 中一个反复出现的问题是弄清楚如何正确传递信息。通常这不是懒惰,而是完全可以访问您需要的变量。那就是说;他显然是对的,threadlocal hack 是一件非常糟糕的事情。
    【解决方案3】:

    您可以使用自定义上下文处理器执行此操作(请参阅 http://docs.djangoproject.com/en/dev/ref/templates/api/

    在这种情况下,您将在 settings.py 文件的同一级别创建一个名为 context_processors.py 的新文件,其中包含:

    def add_session(request):
        return {'session': request.session}
    

    然后,在你的 settings.py 文件中,添加:

    TEMPLATE_CONTEXT_PROCESSORS = ("django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    'context_processors.add_session',)
    

    您现在可以在自定义标记中引用 context['session']。

    请注意,这仅适用于分配了 RequestContext 的模板,如以下代码所示:

    def test(request):
        return render_to_response('test.html',{}, context_instance=RequestContext(request))
    

    【讨论】:

      【解决方案4】:

      我发现这很有用:http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser

      您可以使用中间件获取用户信息并将其存储在本地线程中,然后将其与您的标签定义一起使用。

      【讨论】:

        【解决方案5】:

        使用来自 django-annoying 的 render_to 装饰器似乎是最好的选择(如 another question on stackoverflow 所示)

        【讨论】:

          猜你喜欢
          • 2013-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-04
          • 1970-01-01
          • 2010-12-31
          相关资源
          最近更新 更多