对 Django 数据库值执行计算:views.py、模板还是 Javascript?

Posted

技术标签:

【中文标题】对 Django 数据库值执行计算:views.py、模板还是 Javascript?【英文标题】:Performing calculations on Django database values: views.py, template or Javascript? 【发布时间】:2014-02-14 13:51:42 【问题描述】:

我有一个与 PostgreSQL 数据库接口的 Django 项目;我的一张表大约有 450 行长,每行包含大约十二列。

必须将每一列的值放入不同的公式中以生成我要在模板层中显示的最终数据,但每一行将使用相同的计算集进行处理。 (换句话说,我想执行 12 种不同的计算,每次 450 次。)

我的问题是,在以下方法中,哪种方法是普遍接受的,并且在性能方面是最好的:

A) 将每个计算写成models.py中的模型方法,在views.py中查询所有感兴趣的对象(再次,大约450个)并直接传递给模板,然后使用Django的模板语言编写比如:

<table>
% for item in list %
    <tr>
         <td>item.name</td>
         ...
    </tr>
% endfor %
</table>

(其中.name 是模型方法)

B) 在views.py文件中执行查询计算,并将组织成一个大字典或列表或JSON的结果传递给模板(然后使用模板标签对其进行解析),

C) 将所有感兴趣的对象传递给 A) 中的模板,但使用 javascript 或 jQuery 对每个对象的字段执行计算,

D) 结合 B) 和 C) 以在 views.py 中执行所有数据库查询,然后将 raw 值作为大字典/列表/JSON 对象传递给模板并在这些对象上执行计算使用 Javascript/jQuery 的值。

在我看来,方法 A) 似乎效率最低,因为它需要您在模板层中多次访问数据库。但它使编写视图和模板变得非常简单(只需要你编写 12 种不同的模型方法)。方法 B) 似乎遵循在您的视图中执行尽可能多的逻辑的一般原则,并简单地传递最终结果以显示在模板中。但它使视图函数又长又丑。方法 C) 和 D) 将大部分负载放在最终用户的浏览器上,这似乎真的可以减轻服务器的负载,但如果用户关闭了 JS,显然将无法正常工作。

但同样,我想知道对于这种情况是否有公认的最佳实践,以及从计算的角度来看这是否与 最快 方法相矛盾。

显然,如果我错过了最好的方法,请告诉我它会是什么。

【问题讨论】:

【参考方案1】:

方法(C)和(D),虽然诱人不是要走的路。客户端的计算机可能会很慢,在这种情况下,页面可能会在执行所有这些计算时冻结他们的浏览器。

(A) 似乎是最好的选择,它不应该引起额外的查询。如果您在单个查询集中将对象传递给模板(例如 Model.objects.all()),那么 Django 应该执行单个查询来获取所有对象,然后在模板中调用该方法时不应该有额外的查询被执行。如果您的对象与其他对象相关,并且在计算中使用此关系,请确保使用 select_related 或 prefetch_related 因为在每个模型调用上查询相关对象确实会在每个对象中产生单个查询,除非您预取/选择您的重新准备使用(https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related)。

【讨论】:

感谢您的回复。我的印象是只有 (C) 和 (D) 依赖于客户端的计算机,而 (B) 依赖于服务器,因为所有计算都在视图层执行,并且只有最终值传递给模板? 是的,我打错了,所以是 C 和 D 依赖于客户端。 因此,在极少数情况下,有必要使用处理过的信息构建 python 字典并将其传递给视图,如 (B) 所示,例如,如果您需要计算一次涉及多个寄存器,因此您不能在每个单独的对象上调用类方法,但是,一般来说,拥有一个进行计算的类方法,使用视图来获取必要的查询集,以及然后在模板中调用该方法并显示您喜欢的结果。您可以使用 % with % 模板标签来存储方法调用的结果。 再次感谢@rafadev。出于某种原因,我认为调用模型方法会查询数据库;感谢您清除它。还要感谢您将我指向.select_related(),尽管不幸的是,尽管它将查询数量减少了一半,但它并没有大大加快我的应用程序。我一直在使用方法 (A),但正在寻找一种方法来提高我的应用程序的性能......我想大部分的减速只是来自方法调用,即使它们没有击中数据库。 你在使用 Django 调试工具栏吗?这将帮助您查看每个单独的查询、查询数据库所花费的时间以及 python 处理所有信息所花费的时间......

以上是关于对 Django 数据库值执行计算:views.py、模板还是 Javascript?的主要内容,如果未能解决你的问题,请参考以下文章

Postgres:使用 django 对 json 键进行值查询

在Django中将计算值从视图保存到模型

将 Django/South/PostgreSQL 从按需要计算的汇总值迁移到数据库中维护的汇总值的正确方法是啥?

Django 计数具有重复值的行

在Django模板中从数据库中计算True或False(1或0)值

对计算的 SUM 值执行 AVG