通过jQuery将会话传递给Django模板

时间:2013-09-11 06:48:49

标签: javascript jquery ajax django cookies

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

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还是标题中的某些内容,但结果是当服务器从通过AJAX生成的HTTP请求呈现my_template.html时,没有{{1}对象。当我在浏览器中有机加载它时它可以正常工作。

如果有帮助:

  • 这是在同一个域名。
  • 我已尝试使用.ajax()代替user
  • 我已尝试使用.ajax()代替xhrFields: { withCredentials: true }。 sessionid cookie不存在(虽然csrftoken确实如此,所以我知道我在寻找正确的地方)。

在通过AJAX加载my_template.html这样的网页时,知道如何让my_loader.html中的headers: { 'sessionid': $.cookie('sessionid') }对象可用于服务器吗?

2 个答案:

答案 0 :(得分:1)

我假设您希望在Javascript端评估{% if user.is_authenticated %}?嗯,这不是这个工作原理。 Javascript不知道服务器端有什么,以及如何解析,评估或绑定用户模板变量。

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

答案 1 :(得分: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 %}

tags.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关键字,因为默认情况下会传递请求。
  3. 仍然感谢您的帮助rubber-ducking!如果没有你们强迫我回去质疑我原来的假设,我无法弄清楚真正的问题!