Django,在数据库中存储函数

时间:2016-05-11 19:55:30

标签: python django model functional-programming

我正在尝试找到一种在Django模型中存储函数的方法。 我的用例是一个带有计划和有条件发送的电子邮件系统。

“如果John尚未登录,请立即发送此电子邮件”。

理想情况下,我想创建一个带有测试功能字段的电子邮件。

def my_test(instance):
  if (now() - instance.user.last_login) > timedelta(days=1):
    return False
  return True

Email(send_later_date=now() + timedelta(days=1),
      conditional=my_test)

这是我正在考虑的事情

import importlib

Email(send_later_date=now() + timedelta(days=1),
      conditional='my_app.views.my_test')



class Email(models.Model):
  send_later_date = models.DateTimeField(null=True, blank=True)
  conditional = models.TextField()

  def send_email(self):
    if self.send_later_date < now():
      if not self.conditional:
        function_send_email()
      else:
        function_string = self.conditional
        mod_name, func_name = function_string.rsplit('.',1)
        mod = importlib.import_module(mod_name)
        func = getattr(mod, func_name)
        if func():
          function_send_email()

你会怎么做?我在考虑将函数名称存储在Text字段中。一旦需要,你会如何运行它? ImportLib似乎很有意思......

1 个答案:

答案 0 :(得分:1)

存储函数名称是一种有效的方法,因为它实际上是pickle module使用的方法。这样做有好处(在您的情况下),如果您更新函数的代码,它将自动应用于现有的电子邮件(但要注意向后兼容性)。

为了方便和安全(特别是如果函数名称可能来自用户输入),您可能希望将所有此类函数保留在同一模块中,并仅将函数名称存储在DB中,而不是完整导入路径。因此,您只需导入函数库并使用getattr读取它。我想你也想为这些函数提供参数。如果您不想限制自己使用给定数量/顺序/类型的参数,则可以将数据库中的字典存储为JSON字符串,并使用**运算符对其进行扩展。

import my_app.func_store as store
import json

func = getattr(store, self.conditional)
params = json.loads(self.conditional_params)
if func(**params):
    function_send_email()