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


67

我一直在尝试了解在Django中执行Ajax的最佳方法是什么。通过四处阅读,我了解到常见的过程是:

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

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

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

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

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

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

非常感谢!

更新:请使用代码片段942,因为它是上述代码的增强版本!我发现继承支持通过这种方式效果更好。

Answers:


25

嘿,谢谢vikingosegundo!

我也喜欢使用装饰器:-)。但是与此同时,我一直在遵循我上面提到的摘录建议的方法。唯一的事情是使用代码片段n。942因为它是原始版本的改进版本。运作方式如下:

假设您有一个包含任意可重复使用的有用块的大小的模板(例如,“ subtemplate.html”):

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

通过在视图文件中导入以上代码段,您可以轻松引用模板中的任何块。一个很酷的功能是考虑了模板之间的继承关系,因此,如果您引用包含另一个块的一个块,依此类推,那么一切都应该可以正常工作。因此,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)

7
我知道我迟到了2年,但这是在Django中进行AJAX的正确方法吗?
zengr 2011年

5
@zengr是的,这仍然是正确的方法。即使最初的评论是一年多以前的,我仍在发布此回复,以供其他参考。
Arpit Rai

我这样做:从django.template import loader // t = loader.get_template('subtemp.html')//返回HttpResponse(t.render(context,request))//然后在我的Ajax $(“ #div”)中.html(数据);
amchugh89,2013年

13

这是我将相同的模板用于传统渲染和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


2
很好的例子。并且您可能想要检查request.is_ajax()以确保您没有尝试从正常请求访问视图。
丹尼尔·罗斯曼

7

没有理由您无法使用Ajax返回HTML渲染的位,然后将其插入到现有页面中所需的位置。显然,如果需要,您可以使用Django的模板来呈现此HTML。


我这样做是因为它允许我在使用ajax和不使用ajax的情况下使用相同的模板。只需在ur模板中包括一个子模板,然后使用该服务器的服务器端呈现响应,即可替换最初交付的零件。
vikingosegundo,2009年

抱歉,不是要拒绝您的问题。它是偶然发生的,不幸的是,撤消的宽限期结束后,我注意到了它
Kim

6

当您使用Ajax时,我认为您对模板没有任何用处。模板在那里,因此您可以轻松地在服务器端生成动态HTML,因此在HTML内部几乎没有编程钩子。

在使用Ajax的情况下,您要传递JSON数据,并且可以在Python中根据需要设置其格式。HTML / document元素将通过某些JavaScript库(例如客户端上的jQuery)使用JSON在客户端上生成。

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


感谢您的回答-是的,您是对的,我指的是您必须从服务器端替换一些内部HTML的情况(例如,以重复结构显示的一长串数据,类似表格的表)-在这种情况下如果我决定在应用程序后端构造HTML,则根本不需要JSON。我只是想知道这样做是否比在客户端上使用javascript创建HTML慢。
Magicrebirth,2009年

我看不到任何性能问题。如果使用模板进行渲染或写出json文件没什么大不了
vikingosegundo

考虑我正在使用django table2。我使用自定义格式显示表格。现在,单击表中的按钮后,我需要将表中的数据更新为其他内容,而无需刷新整个页面。@magicrebirth的想法在这样的地方很方便。我不知道如何实现这一点。
Sohaib

3

模板是出于演示目的。使用格式X(JSON,JSONP,XML,YAML,* ml等)的数据响应不是表示形式,因此您不需要模板。只需将数据序列化为X格式,然后以HttpResponse的形式返回即可。


1
嗨,谢谢您的回答。好的,对我来说很明显,模板是用于演示目的的-这就是为什么我也想将它们也用于ajax调用的原因。我从后端获取的数据无论采用哪种格式都已经可以“呈现”,或者必须在您的js代码中进行格式化。就我而言,我需要对html结构中的一长串数据进行ajax更新,这不是一件小事-django模板可以很好地抽象出这种重复的html结构。因此,我最好在后端使用模板并传递html块。.希望现在可以更清楚了
。–

3

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

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

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


1

您可以使用jquery.load()或类似的方法在服务器上生成HTML,然后使用JavaScript将其加载到DOM中。我想有人给这个AJAH打电话了


0

不幸的是,Django模板被设计为仅在服务器端执行。有至少一个项目呈现使用Javascript Django模板,但我没有用它,所以我不知道有多快,以及支持或最新它。除此之外,您必须使用服务器上的Django模板或在客户端上生成动态元素而不使用模板。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.