1

我正在尝试$.load()使用{% if user.is_authenticated %}. 不幸的是,只有在响应 AJAX 生成的 HTTP 请求user时,该对象才在服务器上呈现时在模板中未定义。

my_template.html:

{% if user.is_authenticated %}
  <div>This should be printed</div>
{% else %}
  <div>But this is because there is no user object</div>
{% endif %}

my_loader.html:

{% if user.is_authenticated %}
  <div>This works fine because I'm logged in</div>
{% endif %}
<div id="template'></div>
<script>
  $('#template').load('/my_template.html');
</script>

views.py(使用 django-annoying 的@render_to装饰器):

@render_to('my_template.html')
def my_template(request):
  return {}

据我了解,问题在于 my_loader.html 渲染中可用的“上下文”无法通过.load(). 我不知道这个“上下文”是会话、cookie 还是 header 中的什么,但结果是当服务器从通过 AJAX 生成的 HTTP 请求中呈现 my_template.html 时,没有user对象。当我在浏览器中有机地加载它时,它工作正常。

如果有帮助:

  • 这是在同一个域上。
  • 我已经尝试过使用 .ajax() 代替xhrFields: { withCredentials: true }
  • 我已经尝试过使用 .ajax() 而不是headers: { 'sessionid': $.cookie('sessionid') }. sessionid cookie 不存在(尽管 csrftoken 存在,所以我知道我找对了地方)。

知道如何在user通过 AJAX 加载 my_template.html 之类的页面时使来自 my_loader.html 的对象对服务器可用吗?

4

2 回答 2

1

我假设您希望{% if user.is_authenticated %}在 Javascript 方面进行评估?好吧,这不是这样的。Javascript 不知道服务器端是什么,以及如何解析、评估或绑定用户模板变量。

为了$('#template').load('/my_template.html');工作,你必须确保它在返回之前my_template.html被 Django 渲染。只需创建一个视图(在 Django 中)即可渲染。不用担心会话 - 它应该可以工作,因为随着您的 ajax 请求,cookie(识别会话)也被发送,因此 Django 可以选择正确的会话,并从中提取用户对象。my_template.html

于 2013-09-11T06:57:30.833 回答
0

所以我感觉很糟糕,因为我的示例代码实际上没有任何问题——在我尝试将复杂的实际代码提炼到抽象级别以呈现给大家时,我无意中遗漏了一个复杂性,这是我的问题的根本原因.

事实证明,WTK 和我最初的直觉是,默认情况下 cookie 将在.load()请求中传递,实际上是正确的(检查 HTTP 请求确认)。

所以真正的问题是,实际上,我没有一个模板,而是两个嵌套的,而后者实际上是一个模板标签。所以真正的结构更像是:

my_template.html:

Some stuff
{% my_template_tag %}

my_template_tag.html:

{% if user.is_authenticated %}
  <div>This should be printed</div>
{% else %}
  <div>But this is because there is no user object</div>
{% endif %}

标签.py

@register.inclusion_tag('my_template_tag.html')
def my_template_tag():
  return {}

...其中views.py 和my_loader.html 与上面介绍的相同。回想起来,我应该注意到my_template_tag()没有带request参数,这意味着它不会在 RequestContext 中user可用。基本上:模板标签并不request像模板那样在其上下文中隐含地包含,而且由于user只是来自request.user它也不可用。

对于以后可能会阅读本文的人,有两种解决方案:

  1. 手动将user对象作为参数传递给 template_tag。
  2. {% include %}如果可能,请与关键字一起使用with,因为它默认通过请求。

仍然感谢您的所有帮助!如果没有你们强迫我回去质疑我最初的假设,我不可能找出真正的问题!

于 2013-09-11T07:42:13.063 回答