使用JQuery和AJAX在Django中刷新div

时间:2010-11-18 17:50:42

标签: jquery ajax django

我正在尝试使用AJAX和JQuery(在Django中)刷新页面的某个部分。我怎样才能让它重新显示div而不是整个页面。

    // In my template
    var tag_cloud_floor = function(floor) {
    $.ajax({ url: "/{{ user }}/{{ tag }}/",
                     data: {tag_cloud_floor: floor},
                     type: 'POST',
                     success: function(data) {
                         $('#tag_cloud).html(data);
                     },
    });

};

以下是我的观点。

@login_required
def tag_page(request, username, tag):
  if username == request.user.username:
    tags = request.user.userprofile.tag_set.all()

    if request.is_ajax() and request.POST:
      floored_tags = []
      for t in tags:
        if t.item_set.all().count() >= int(request.POST['tag_cloud_floor']):
          floored_tags.append(t)
      tags = floored_tags

    tag = Tag.objects.get(title=tag)
    items = tag.item_set.all()
    return render_to_response("tag_page.html", { 'user': request.user , 
                                              'tag': tag,
                                             'tags': tags,
                                            'items': items })
  else:
  return HttpResponseRedirect('/' + request.user.username + '/')

目前,它将整个html页面放入#tag_page div。我希望它用新的#tag_page div替换旧的#tag_page div。如果我用$('#tag_cloud').html(data);替换$('body').html(data);,它会将整个页面刷新为应该如何,但我觉得刷新整个页面是一种浪费。

如果有更好的方法,请告诉我。

3 个答案:

答案 0 :(得分:11)

使用load

$('#tag_cloud').load(' #tag_cloud')

(注意load参数中的前导空格;这指定一个空字符串[评估到当前页面]作为源,“#tag_cloud”作为要加载的片段)

这实际上会将#tag_cloud(包括其外部html)加载到#tag_cloud中,因此您基本上会在DOM中获得以下结构:

<div id="tag_cloud">
    <div id="tag_cloud">
        <span>tag</span> ...

要解决此问题,只需unwrap孩子:

$('#tag_cloud').load(' #tag_cloud', function(){$(this).children().unwrap()})

哦,顺便说一句......你可以在这里试试吧!只需将以下内容粘贴到Firebug控制台中,然后观看侧边栏自动重新加载即可。你会注意到一些脚本代码在探索;那是jQ的HTML安全过滤器,为你禁用了<script>元素(有时可能很烦人)。

$('#sidebar').load(' #sidebar', function(){$(this).children().unwrap()})

答案 1 :(得分:7)

首先,看起来您的代码已损坏 - 这不是有效的Javascript / jQuery指令:

$('#tag_cloud).html(data);

您需要添加缺少的引号:

$('#tag_cloud').html(data);

至于仅刷新一个div,我会将该div的内容提取到单独的模板my_div.html,并使用{% include "my_div.html" %}将其包含在主页面模板中。然后,在我的AJAX视图中,我将渲染并仅返回呈现的my_div.html

答案 2 :(得分:3)

在我们的项目中,我们有太多单独的Ajax视图,编写中间件并重用相同的视图是有意义的。我最近创建了一个application,允许客户端请求任何页面的部分内容。

比方说,页面/usual_page/有这个模板:

{% extends "another_template.html" %}
{% block title %}Usual page{% endblock %}
{% block content %}...{% endblock %}
{% block my_widget %}widget code{% endblock %}

如果您安装中间件并发出类似/usual_page/?partial=my_widget的GET请求,它会向客户端发送此数据:

{"blocks": {"my_widget": "widget code"}}

或者,如果您执行/usual_page/?partial=title,content,它将发送以下内容:

{"blocks": {"title": "Usual page", "content": "..."}}

也可以请求父模板中的其他块。块在层次结构中的位置并不重要,只关注它存在于普通页面中(没有?partial参数的页面)。

the BitBucket repo中,我有一个演示项目,其中包含一个可自动完成工作的模块。它允许您使用History.pushState技巧并加载页面的一部分并将它们插入到文档中。