将Django与Ajax库集成的最佳方法

8 投票
5 回答
4754 浏览
提问于 2025-04-16 19:19

显然,不同的情况适合不同的工具,但有什么好的方法可以把JavaScript库和Django应用结合起来呢?

我打算使用jQuery,主要是因为它看起来很流行而且功能强大(不过我也愿意听听其他建议)。

有没有一些在Python这边特别有用或者必不可少的库呢?还是说最好直接创建JSON视图,然后手动写JavaScript(使用合适的JavaScript框架)?

我简单看过Dajax,但根据那点可怜的文档,似乎并没有给我太多帮助。我当然更希望能找到一些文档更丰富的东西。

这里的其他回答提到pjax在很多浏览器上可能不太好用,所以这个就不考虑了。

编辑:谢谢大家。我会看看tastypie来简化一些JSON视图的创建,并且准备手动写一些JavaScript(我今年早些时候试过一点,感觉比90年代末好多了)。

5 个回答

5

我建议你自己创建一些 JavaScript 和 AJAX 的视图。Ruby on Rails 以前有个问题,就是强迫大家以特定的方式使用 AJAX,这让很多人感到困扰。最近,他们终于意识到这个问题,开始把 AJAX 和框架分开,这样你就可以随意使用你喜欢的库了。

这是 Django 的一个特点。虽然看起来可能更复杂,但相信我,能够从头到尾掌控整个过程,最终会好得多。

8

记住,虽然是ajax请求,并不意味着你必须返回一大堆json数据。其实你可以返回一个已经渲染好的模板。

确实,所谓的“正确做法”是用javascript来构建所有的标签,然后用json数据填充这些标签,但说实话,这实在是太麻烦了……以至于他们正在开发一种jquery模板语言来简化这个过程。

另外,你不能随便把查询结果直接扔出去。你需要手动构建你的json数据。很多教程和建议似乎都忽略了这一点。从django的文档来看:

def convert_context_to_json(self, context):
        "Convert the context dictionary into a JSON object"
        # Note: This is *EXTREMELY* naive; in reality, you'll need
        # to do much more complex handling to ensure that arbitrary
        # objects -- such as Django model instances or querysets
        # -- can be serialized as JSON.
        return json.dumps(context)

我做的其实是为新的基于类的视图写了一个混合类,根据是否是ajax页面加载来渲染不同的模板。我把想要返回的内容放在一个片段中,然后在另一个包装模板里扩展base.html,并包含这个片段模板。

class AjaxTemplateMixin(TemplateResponseMixin):
    ajax_template_name = None

    def get_template_names(self):
        if self.ajax_template_name and self.request.is_ajax():
            self.template_name = self.ajax_template_name

        return super(AjaxTemplateMixin, self).get_template_names()    

这样我就只需要写一次模板,而不必在javascript中手动构建DOM元素。这额外的工作量非常少,尤其是如果你不是在写一个api,这种做法是最合适的。

2

在Python这边,我建议你看看pistontastypie

(我自己也是从AJAX和Django开始的,之前还发现过Dajax,但最后选择了piston——我觉得它更符合‘unix风格’,不太喜欢那种一体化的解决方案。虽然piston已经很久没有更新了,所以我推荐tastypie,这个项目还在积极维护。)

补充一下,还有一个类似的项目,django-rest-framework。我自己还没用过,它比较新。

基本上,这些库可以帮助你为你的模型创建一个完整的可读写API,这样你就可以通过HTTP从JavaScript进行创建、读取、更新和删除操作。你不需要定义任何视图或序列化器。相反,你只需要定义一些资源,我觉得这是一种不错的抽象方式。

而且通常只需要几行代码,特别是当你的资源与模型关联时。

不过,如果你需要更复杂的功能,你可以重新考虑你的设计自己写视图。使用基于类的视图,这也很简单。你可以看看这个代码片段作为例子。

撰写回答