我正在尝试找到一种在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
似乎很有意思......
答案 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()