在Ajax调用之后使用Django模板呈现JSON对象

时间:2009-05-19 11:36:21

标签: python ajax django json templates

我一直在努力了解在Ajax中进行Django的最佳方式是什么。通过阅读这里和那里的东西,我收集了共同的过程:

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

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

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

  5. 现在,我还没有得到的是 Django模板如何与所有这些相关?显然,我们根本没有充分利用模板的强大功能。 理想情况下,我认为传回JSON对象和模板名称会很好,这样可以迭代数据并创建HTML块。但也许我在这里完全错了......

    我发现朝这个方向发展的唯一资源是this snippet (769),但我还没有尝试过。 显然,在这种情况下会发生的是,所有生成的HTML都是在服务器端创建的,然后传递给客户端。 JavaScript-callback函数只需要在正确的位置显示它。

    这是否会导致性能问题?如果没有,即使不使用上面的代码片段,为什么不使用Python而不是前端直接在后端格式化HTML?

    非常感谢!

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

8 个答案:

答案 0 :(得分:25)

嘿谢谢vikingosegundo!

我也喜欢使用装饰器:-)。 但与此同时,我一直在关注上面提到的片段所建议的方法。唯一的事情,请使用the snippet n. 942,因为它是原始版本的改进版本。以下是它的工作原理:

想象一下,你有一个模板(例如'subtemplate.html'),其大小包含一个你可以重复使用的有用块:

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

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

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)

答案 1 :(得分:13)

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

模板:

<div  id="sortable">

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

包含的模板(aka:subtemplate):

<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

答案 2 :(得分:7)

没有理由不能使用Ajax返回渲染的HTML,并将其插入到您想要的点的现有页面中。显然,如果你愿意,你可以使用Django的模板来渲染这个HTML。

答案 3 :(得分:6)

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

如果是Ajax,则传递JSON数据,您可以根据需要在Python中对其进行格式化。 一些JavaScript库使用JSON在客户端生成HTML /文档元素,例如:客户端的jQuery。

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

答案 4 :(得分:3)

模板用于演示文稿。以格式X(JSON,JSONP,XML,YAML,* ml等)的数据进行响应不是表示,因此您不需要模板。只需将数据序列化为格式X并将其返回到HttpResponse。

答案 5 :(得分:3)

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

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

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

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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