我有一个非常简单的Django应用程序,允许用户提交一个表单,并根据国家,持续时间和价格查看过滤后的假期列表。
我想在前端使用Backbone,这样启用了JS的用户就不需要GET来查看结果,而是可以动态加载它们。
我想使用渐进式增强,以便使用JS的用户获得Backbone体验,而不使用JS的用户仍然可以使用表单。我也想遵循DRY原则。
我的问题是如何最好地做到这一点。是否有将两者结合使用且重复最少的例子?我特别想的是:- Routing一个URL,比如
/italy/1-week/from-500-to-1000/
——我现在是否需要写两组路由代码,一个在Django的urls.py
中,一个在Backbone的路由器中,来获取国家/持续时间/价格参数? - 过滤数据,基于参数-我需要写两种不同的方式来做到这一点,一个在
views.py
和一个在骨干?(我想我至少可以为两个调用使用一个API。) - 在模板中呈现 -我是否需要为Django和Backbone编写一个列表模板,或者可以使用相同的模板?
到目前为止,我发现最好的(唯一的)将Backbone集成到Django中的例子是Josh Bohde的Django Backbone repo,它没有逐步增强。
我还发现了一篇关于Backbone和Rails的渐进式增强的博客文章,但如果能在Django中看到类似的东西,那就更好了。
更新:刚刚在一个类似的话题上发现了这个问题-情况真的像答案听起来那样绝望吗?
情况真的像答案听起来那么绝望吗?
差不多。但是,由于我工作的网站曾经是基于django的,但现在正在成为基于backbone的,我可以提供一些想法:
将/italy/1-week/这样的URL从500路由到1000/——我现在是否需要编写两组路由代码,一组在Django的urls.py中,另一组在Backbone的router中,来获取国家/持续时间/价格参数?
是的,但是有一些方法可以减少重复。我们采用的方法是让Django将所有url作为JS变量输出到我们的主HTML页面模板中:
<script>
URLS.report_error = "{% url app.log_client_error_view %}";
URLS.access_file = "{% url app.access_file_view 12345 %}";
</script>
现在我们有一个使用12345作为我们生成的每个URL的参数的模式;这使得将URL转换回主干路由正则表达式变得容易,因为我们基本上可以用([^/]+)
替换12345
。
为了充分披露,我们确实有一堆路由正则表达式是"手工"编写的,但这并不是因为我们不能自动化它们;这只是因为我们正在远离Django方面的东西,所以我们没有理由清理这些代码。如果你想要同时支持这两种语言,你应该能够想出一个相当简单的翻译方案。
过滤数据,基于参数-我需要写两个独立的方式来做这件事,一个在views.py和一个在Backbone?(我假设我至少可以为两个调用使用一个API。)
这在任何站点上都是不可避免的问题,不仅仅是Backbone/Django。您必须使用来过滤服务器端的数据,因为您永远不能信任客户端(例如,用户可以禁用JS)。与此同时,仅服务器端过滤是20世纪90年代的事情,因此您需要在客户端也创建(复制)过滤逻辑(这样您就可以告诉用户"您忘记提供字段X",而无需等待到服务器的往返)。
然而,有一些方法可以限制这种重复。我自己没有做过这部分,但我知道一个同事设法以一种奇怪的方式使用Django表单(他使用Django提供的表单,然后稍微解析它们,然后将它们用作骨干视图的模板)。这并没有完全消除重复,不幸的是我不记得任何细节,但它确实有帮助。
在模板中渲染——我是否需要为Django编写一个列表模板,为Backbone编写另一个列表模板,或者可以使用相同的模板?
Handlebars模板的语法与Django模板相似,如果你所做的只是变量({{foo}}
)。如果你想在两者之间共享逻辑,两者的语法略有不同({% if foo %}
vs. {{#if foo}}
),但它们足够接近,如果你不介意做一点解析工作,你应该很容易地将一个转换成另一个。
所以,是的,你承担了很多工作,只是为了支持一小部分用户(那些浏览器不支持Backbone的用户)。我强烈建议你在Google Analytics(分析)之类的网站上查看一下用户的浏览器统计数据(或者如果你的网站还没有上线,可以查看一下一般的网络统计数据),然后决定为了一小部分用户群而付出这么大的代价是否值得。如果没有统计数据,你就不知道这个百分比有多小,这显然是决定的关键因素。
对我们来说,选择是显而易见的:要求我们的用户使用本世纪开发的浏览器(这几乎是所有Backbone需要的),并且只使用所有Backbone。但如果这个选择对你来说不是那么明显……祝你好运,尝试干你的Django和主干代码:-)
我刚刚读到一个完全不同的解决方案来解决这个问题,我想我要分享:HTML快照(https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot)。我链接的页面是基于java的,但你当然可以在Python/Django中设置类似的东西。
基本的想法是,你在你的服务器上设置一个无头Javascript运行程序,当一个网络爬虫到达你的网站时,你使用JS运行程序生成的HTML,你的主干代码将在客户端正常运行。然后,它将HTML发送回网络爬虫,让您拥有客户端和服务器的一组代码。
运行无头JS运行程序可能会有一些小的潜在问题(它们与web浏览器的内置JS不是100%相同),但当用于这种"HTML快照"方法时,它们不应该太相关。
不确定您是否还在努力解决这个问题,但我一直在努力寻找解决这个问题的一些方法。我为此写了一篇初步的博文:
JavaScript框架与Django的互操作性
我将在几周后跟进一个使用Django + Backbone +木偶+一些其他插件完成的"Notes"应用程序的完整示例。
代码将演示如何在客户端使用Django模板,所以它可能对你有用。
如果有兴趣,你可以关注我的博客或twitter @sid_azad