【问题标题】:Refresh a div in Django using JQuery and AJAX使用 JQuery 和 AJAX 在 Django 中刷新 div
【发布时间】:2010-11-18 17:50:42
【问题描述】:

我正在尝试使用 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);,它会将整个页面刷新到应有的状态,但我认为刷新整个页面是一种浪费。

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

【问题讨论】:

  • 另外,是否可以将 ajax 工作分离到与初始页面加载的视图不同的视图?
  • 当然可以将功能分离出来;使用单独的 URL 创建一个单独的视图,并让该视图仅返回标签数据。现在,您是以 JSON 格式返回它并重建页面上的标签,还是将其作为 HTML 片段返回并简单地将其插入页面,这取决于您。如果您计划在您的网站上使用大量 AJAX,请查看 django-piston

标签: jquery ajax django


【解决方案1】:

使用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 安全过滤器为您禁用 &lt;script&gt; 元素(有时可能很烦人)。

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

【讨论】:

  • 首先我否决了这个答案,然后我检查了load() docs,注意到“加载页面片段”部分并撤销了投票:-) 不错的东西,尽管它不必要地重新生成了整个页面。
  • @Tomasz 好吧,那么感谢您阅读文档!是的,我通常会使用活塞(甚至只是一个返回 json 数据的简单视图)来进行这样的交互,但 OP 似乎正在尝试做load 的本意。
【解决方案2】:

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

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

您需要添加缺少的引号:

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

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

【讨论】:

  • $('#tag_cloud').html(data);实际上是一个有效的功能(我只是忘记了第二个引号)。我最终保留了它,包括第二个文件,并传递了该文件的数据。
  • @Josh:是的,我的意思是缺少的报价。
  • @TomaszZieliński 你的回答很好,但你能解释一下吗?我是 Django 的新手。
【解决方案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 技巧并加载部分页面并将它们插入到文档中。

【讨论】:

  • 这很聪明。我打算自己写一些类似的东西。但我看到这个答案是从 2011 年开始的,Django 目前是否内置了类似的东西,还是我们仍然需要这个解决方案?
猜你喜欢
  • 1970-01-01
  • 2013-04-02
  • 2017-11-16
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多