Django中用户定义的派生数据

Posted

技术标签:

【中文标题】Django中用户定义的派生数据【英文标题】:User-defined derived data in Django 【发布时间】:2009-05-11 08:32:27 【问题描述】:

我如何让我的用户将他们自己的自定义公式应用于数据表以派生新字段?

我正在开发一个Django 应用程序,它将为开放网络上的订阅用户存储和处理大量数据。在一页请求中考虑 100-10,000 个传感器读数。我将使用这些数据绘制图表并显示包含它的表格。我希望我的用户定义传感器组,他们将在我的网站上注册自己(即它们对应于 django 模型)。

我想让用户能够创建从他们的传感器数据派生的字段(作为设置过程的一部分)。例如,用户可能知道他们的平均房屋温度为 (温度传感器 1 + 温度传感器 2) / 2,并希望将其显示在图表上。他们可能还想要一些更有趣的东西,比如太阳能热水加热是(温度输出 - 温度输入)* 流量 * 转换常数。然后,我将为他们以及查看此传感器数据页面的其他所有人保存这些定义的公式。

主要问题是如何定义系统中心的公式。我是否只有一个用户定义的字符串来定义公式(比如 100 个字符长)并自己解析它 - 用输入样本替换用户定义并将其命名为 toast?

更新

最后我得到了我想要的答案:一种评估服务器上存储的用户功能的安全方法。在定义函数时也在客户端上评估相同的函数将是使 UI 直观的好方法。

【问题讨论】:

【参考方案1】:

取决于你的客户是谁。

如果这是在 WWW 上“向公众开放”,您必须自己解析表达式。您可以使用 Python 编译器来编译 Python 语法。您还可以为 Python 语法的子集发明自己的编译器。有很多例子;从ply 项目开始。

如果这是内部的(“防火墙后”),请发布一段 Python 代码并执行该代码。

给他们一个可用的环境from math import * 功能。

在他们提供的代码行周围折叠以下内容:

def userFunc( col1, col2, col3, ... ):
   result1=  their code goes here 
   return result1

然后你可以执行函数定义并使用定义的函数而不发生坏事。

虽然有些人喜欢吹嘘 exec 是“安全问题”,但它只是用户共享密码的安全问题,并且管理员在编程时会故意做一些愚蠢的事情,例如删除重要文件或随机关闭电源正在运行。

exec 仅在您允许任何人访问时才会出现安全问题。对于内部应用程序,您了解用户。训练他们。

【讨论】:

感谢 ply 项目的指针。这是对 WWW 方法的一种开放方式,我完全希望公众只是徘徊。这确实排除了 exec,因为饼干比我更有创意。 第一个 PLY 示例(请参阅dabeaz.com/ply/example.html)正是我所需要的。非常感谢你【参考方案2】:

我会弄清楚您想要支持哪些操作 [+,-,*,/,(,),etc] 并开发客户端 (javascript) 来编辑这些值并将其应用于数据的新字段。我认为没有必要在服务器端做任何事情,因此您最终将获得响应更快、更愉快的用户体验。

如果您允许用户保存他们的公式并在他们重新访问该网站时重新加载它们,您可以让他们的浏览器进行所有计算。只需提供一些通用方法来添加通过将其论坛之一应用于您的数据而生成的数据列。

我想下一步是允许他们将这些操作应用于新生成的列。

您是否考虑过将他们的数据发布到 Google 电子表格中?这将节省大量开发工作,因为它们已经允许您定义公式等并将其应用于数据。我不太确定数据限制(您可以发布和操作多少数据)请注意。

【讨论】:

我完全同意使用 JavaScript 来改善体验。可以说,除了某种 UI 来定义它们之外,我还没有考虑过人们“即时”添加公式的可能性。我计划跟踪网站的用户(他们将成为注册客户),因此保存公式应该非常简单。我已经在考虑使用 YUI DataTable (developer.yahoo.com/yui/datatable)。 只要您可以限制用户可以操作的内容,javascript 应该可以让解释公式变得相当容易。 要考虑的另一件事是,如果您每次都存储他们的结果,您最终会得到大量数据。 YUI 数据表看起来是个不错的起点。我会使用 Flotr 来绘制图表 (solutoire.com/flotr)。 我不打算存储结果,只存储公式。我将重新计算数据,可能会在几天内多次计算。在服务器上缓存它应该很快。 Javascript 是一个不错的选择。它还将增加服务器代码的可伸缩性,因为处理将成为浏览器的负担。此外,如果用户确实设法创建了类似无限循环的东西,它只会影响他们的浏览器,而不是服务器。我在ETFtable.com 上做了类似的事情,我将大量历史数据下载到用户的浏览器,并针对 javascript 中的技术分析函数运行它,然后将数据输出到 YUI 数据表。【参考方案3】:

另一个用户在 C 中询问了 similar question。 在那篇文章中,Warren 建议可以从

解析和转换公式
(a + c) / b 

转入reverse polish notation

a c + b / 

哪个更容易处理。

在这种情况下,您可以截取公式模型的保存并从用户定义的公式生成后缀符号。一旦有了后缀符号,编写一个从左到右计算公式的循环就相当简单了。

至于在 Django 中的实现,剩下的核心问题是如何将不同的输入字段映射到公式中。简单的解决方案是表示派生字段的模型使用与每个输入定义的符号名称(“a”、“b”或“c”)的多对多关系。

如果性能真的很关键,您可能会在将后缀公式应用于数据之前以某种方式进一步预处理它。

【讨论】:

你的问题很有趣,但这个答案很难理解。看起来很简洁,没有任何解释。 感谢您的评论,希望新版本更容易理解。

以上是关于Django中用户定义的派生数据的主要内容,如果未能解决你的问题,请参考以下文章

Django 自定义用户认证

在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型

Write语句不能在用户定义的格式化I / O过程中为派生类型生成新行

使用注册表单添加到自定义用户字段(django)

如何在用户导航期间在 Django 中保存自定义用户模型

Django - Django ORM 如何管理用户在数据库中上传的表