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

2024-04-25 19:25:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在试图了解在Django中做Ajax的最佳方法是什么。通过阅读这里和那里的资料,我发现通常的过程是:

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

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

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

现在,我仍然没有得到的是,Django模板与所有这些有什么关系?显然,我们根本没有利用模板的威力。 理想情况下,我认为最好传递回一个JSON对象和一个模板名,这样数据就可以被迭代并创建一个HTML块。但也许我完全错了。。。

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

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

非常感谢!

更新:请使用snippet 942,因为它是上述版本的增强版!我发现继承支持通过这种方式工作得更好。。


Tags: 数据对象django方法函数模板json客户端
3条回答

嘿,谢谢维金戈塞贡多!

我也喜欢用装饰工。 但与此同时,我一直在遵循上面提到的片段所建议的方法。唯一的问题是,改用the snippet 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)

没有理由不能使用Ajax返回一点呈现的HTML,并在需要的时候将其插入到现有页面中。显然,如果需要的话,可以使用Django的模板来呈现这个HTML。

下面是我如何使用相同的模板进行传统渲染和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

相关问题 更多 >