【问题标题】:Rendering JSON objects using a Django template after an Ajax call在 Ajax 调用之后使用 Django 模板呈现 JSON 对象
【发布时间】:2010-10-27 07:15:04
【问题描述】:

我一直试图了解在Django 中执行Ajax 的最佳方式是什么。通过阅读这里和那里的东西,我收集到常见的过程是:

  1. 使用一些 JavaScript 库(例如 jQuery)制定您的 Ajax 调用,在 Django 中设置一个 URL 模式来捕获调用并将其传递给视图函数

  2. Python 视图函数中检索您感兴趣的对象并以 JSON 格式或类似格式将它们发送回客户端(通过使用内置的序列化模块或simplejson

  3. 在 JavaScript 中定义一个回调函数,接收 JSON 数据并解析它们,以便创建需要显示的任何 HTML。最后,JavaScript 脚本将 HTML 放在它应该保留的任何位置。

现在,我仍然不明白Django 模板与所有这些有什么关系? 显然,我们根本没有利用模板的力量。 理想情况下,我认为传回 JSON 对象和模板名称会很好,这样可以迭代数据并创建 HTML 块。但也许我在这里完全错了......

我发现的唯一资源是this snippet (769),但我还没有尝试过。 显然,在这种情况下将发生的事情是所有生成的 HTML 都是在服务器端创建的,然后传递给客户端。 JavaScript 回调函数只需将其显示在正确的位置即可。

这会导致性能问题吗?如果不是,即使不使用上面的 sn -p,为什么不直接在后端使用 Python 而不是前端格式化 HTML?

非常感谢!

更新:请使用snippet 942,因为它是上述版本的增强版!我发现这样的继承支持效果更好..

【问题讨论】:

    标签: python ajax django json templates


    【解决方案1】:

    嘿,谢谢 vikingosegundo!

    我也喜欢使用装饰器 :-)。 但与此同时,我一直在遵循我上面提到的 sn-p 建议的方法。只有一件事,改用the snippet n. 942 因为它是原始版本的改进版本。以下是它的工作原理:

    假设您有一个模板(例如,'subtemplate.html'),大小不限,其中包含可以重复使用的有用块:

         ........
        <div id="results">          
            {% block results %}
                {% for el in items %}
                       <li>{{el|capfirst}}</li>
                {% endfor %}
            {% endblock %}      
        </div><br />
         ........
    

    通过在您的视图文件中导入上面的 sn-p,您可以轻松引用模板中的任何块。一个很酷的特性是考虑了模板之间的继承关系,所以如果你引用一个包含另一个块的块等等,一切都应该正常工作。所以,ajax 视图看起来像这样:

    from django.template import loader
    # downloaded from djangosnippets.com[942]
    from my_project.snippets.template import render_block_to_string
    
    def ajax_view(request):
        # some random context
        context = Context({'items': range(100)})
        # passing the template_name + block_name + context
        return_str = render_block_to_string('standard/subtemplate.html', 'results', context)
        return HttpResponse(return_str)
    

    【讨论】:

    • 我知道我迟到了 2 年,但这是在 Django 中做 AJAX 的正确方法吗?
    • @zengr 是的,这仍然是正确的做法。即使最初的评论是一年多前的,我还是发布这个回复以供其他人参考。
    • I do: from django.template import loader // t = loader.get_template('subtemp.html') // return HttpResponse(t.render(context, request)) // 然后在我的Ajax $( "#div" ).html(data);
    【解决方案2】:

    这是我如何使用相同的模板进行传统渲染和 Ajax 响应渲染。

    模板:

    <div  id="sortable">
    
    {% include "admin/app/model/subtemplate.html" %}
    </div>
    

    包含的模板(又名:子模板):

    <div id="results_listing">
    {% if results %}
        {% for c in results %}
            .....
        {% endfor %}
    {% else %}
    

    Ajax 视图:

    @login_required
    @render_to('admin/app/model/subtemplate.html')#annoying-decorator
    def ajax_view(request):
        .....
    
        return { 
            "results":Model.objects.all(),
        }      
    

    当然你可以使用 render_to_response。但我喜欢那些烦人的装饰器:D

    【讨论】:

    • 很好的例子。您可能需要检查 request.is_ajax() 以确保您没有尝试从正常请求访问视图。
    【解决方案3】:

    没有理由不能使用 Ajax 返回呈现的 HTML 位,并将其插入到现有页面中所需的位置。显然,如果你愿意,你可以使用 Django 的模板来呈现这个 HTML。

    【讨论】:

    • 我这样做是因为它允许我在有和没有 ajax 的情况下使用相同的模板。只需在您的模板中包含一个子模板并使用此模板服务器端呈现响应,这将替换最初交付的部分。
    • 抱歉,并不是要否决您的问题。它是偶然发生的,不幸的是我在撤消的宽限期结束后注意到了它......
    【解决方案4】:

    当您使用 Ajax 时,我认为您对模板没有任何用处。 模板在那里,您可以轻松地在服务器端生成动态 HTML,因此它在 HTML 中提供了很少的编程钩子。

    在 Ajax 的情况下,您传递 JSON 数据,您可以在 Python 中根据需要对其进行格式化。 并且 HTML/document 元素将由一些 JavaScript 库使用 JSON 在客户端生成,例如客户端的 jQuery。

    也许如果你有一个从服务器端 HTML 替换一些内部 HTML 的非常具体的情况,那么也许你可以使用模板,但在这种情况下你为什么需要 JSON? 您可以通过 Ajax 查询 HTML 页面并更改内部或外部或任何 HTML。

    【讨论】:

    • 感谢您的回答 - 是的,您是对的,我指的是您必须从服务器端替换一些内部 HTML 的情况(例如,以重复结构呈现的一长串数据,类似于table) - 在这种情况下,如果我决定在应用程序后端构建我的 HTML,则根本不需要 JSON。我只是想知道这样做是否会比在客户端上使用 javascript 创建 HTML 慢。
    • 我看不到任何性能问题。如果你用模板渲染或写出一个 json 文件应该没多大关系
    • 考虑到我正在使用 django tables2。我使用自定义格式显示表格。现在单击表格中的按钮时,我需要将表格中的数据更新为其他内容,而无需刷新整个页面。 @magicrebirth 的想法在这些地方派上用场。不过我不知道如何实现。
    【解决方案5】:

    模板用于演示。使用 X 格式的数据(JSON、JSONP、XML、YAML、*ml 等)响应不是演示文稿,因此您不需要模板。只需将数据序列化为 X 格式并在 HttpResponse 中返回即可。

    【讨论】:

    • 您好,感谢您的回答。好的,我很清楚模板是用于演示目的的——这正是我想将它们也用于 ajax 调用的原因。我从后端以任何格式获取的数据要么已经“可展示”,要么必须在您的 js 代码中进行格式化。在我的例子中,我需要在 html 结构中对一长串数据进行 ajax 更新,这并不重要——而 django 模板在抽象这种重复的 html 结构方面效果很好。所以我最好在后端使用模板并传递一个 html 块..希望现在更清楚..
    【解决方案6】:

    虽然模板确实只是用于演示目的,但无论您是在服务器端还是客户端执行它都无关紧要。这一切都归结为将执行操作的控制逻辑与仅负责创建标记的视图逻辑分开。如果您的 javascript 控制逻辑必须处理您如何渲染或显示 HTML,那么您可能做错了,但是如果您将该渲染逻辑隔离到另一个对象或函数,并且只是将渲染所需的数据传递给它,那你应该没问题;它反映了我们如何在服务器端分离控制器、模型和视图。

    看一下github项目:http://github.com/comolongo/Yz-Javascript-Django-Template-Compiler

    它将 django 模板编译为优化的 javascript 函数,这些函数将使用您传递的数据生成您的演示文稿 html。编译后的函数是纯 javascript,因此不依赖于其他库。由于模板是在运行时编译而不是解析的,字符串和变量都已经放入了只需要连接的 javascript 字符串中,因此与需要您的技术相比,您可以获得 巨大 的速度提升进行 dom 操作或脚本解析以获得最终呈现。现在只有基本的标签和过滤器,但对于大多数事情来说应该足够了,随着人们开始对它们提出请求或开始为项目做出贡献,将会添加更多标签。

    【讨论】:

      【解决方案7】:

      您可以使用jquery.load() 或类似方法,在服务器上生成 HTML 并使用 JavaScript 将其加载到 DOM 中。我想有人称它为 AJAH

      【讨论】:

        【解决方案8】:

        不幸的是,Django 模板被设计为仅在服务器端执行。有 at least one project to render Django 模板使用 Javascript,但我没有使用它,所以我不知道它有多快、支持得好还是最新。除此之外,您必须要么在服务器上使用 Django 模板,要么在客户端生成动态元素而不使用模板。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-13
          • 1970-01-01
          • 2018-04-06
          • 2014-06-16
          • 1970-01-01
          • 2018-03-01
          • 2020-08-31
          • 1970-01-01
          相关资源
          最近更新 更多