2010-11-18 72 views
4

我想用AJAX和JQuery(在Django中)刷新我的页面的某个部分。我怎么才能让它重新显示只有div,而不是整个页面。使用JQuery和AJAX刷新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。如果我用替换$('body').html(data);它刷新整个页面应该如何,但我刷新整个页面是浪费。

如果有更好的方法来做到这一点,让我知道。

+0

另外,是否有可能将ajax工作分开到与初始页面加载视图不同的视图? – Josh 2010-11-18 18:09:04

+1

当然,您可以将功能分开;使用单独的URL创建单独的视图,并使该视图返回标记数据。现在,无论是以JSON格式返回并重新构建页面上的标记,还是将其作为HTML片段返回并将其插入页面,都取决于您。如果你计划在你的网站上使用很多AJAX,请查看[django-piston](http://bitbucket.org/jespern/django-piston/wiki/Home) – eternicode 2010-11-19 20:06:53

回答

7

首先,它看起来像你的代码被打破 - 这不是一个有效的JavaScript/jQuery的指令:

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

您需要添加缺少的报价:

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

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

+0

$('#tag_cloud')。html (数据);其实是一个有效的功能(我只是忘了第二个报价)。我结束了,包括第二个文件,并传递数据该文件。 – Josh 2010-11-19 19:18:45

+0

@Josh:是的,我的意思是缺少的报价。 – 2010-11-19 19:53:32

+0

我们如何做到这一点,你可以指向我的一些链接,我可以学习这一点我有一个单独的文件中的表我想更新基于用户从数据库中点击按钮。 – Sohaib 2013-07-01 16:04:14

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()}) 

哦,对了......你可以在这里SO试试这个!只需将以下内容粘贴到Firebug控制台中,然后观看边栏自动重新加载。你会注意到一些脚本代码戳穿;这是jQ的HTML安全过滤器为你禁用<script>元素(有时可能会令人讨厌)。

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

首先我低估了这个答案,然后我检查了[load()docs](http://api.jquery.com/load/),注意到了“加载页面片段”部分并反转了投票:-)好东西,虽然它不必要地重新生成整个页面。 – 2010-11-19 19:52:29

+0

@Tomasz很好,谢谢你阅读文档,然后!是的,我通常会使用活塞(或甚至只是一个简单的视图,返回json中的数据)进行这种交互,但是OP似乎试图去做“加载”的目的。 – eternicode 2010-11-19 20:05:20

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技巧并加载部分页面并将它们插入到文档中。

+0

这非常聪明。我本人会写一些类似的东西。但我看到这个答案是从2011年开始的,Django目前是否有类似的内置或者我们仍然需要这种解决方案? – 2015-08-27 18:32:20