存储函数或类的Django模型字段

时间:2014-01-03 20:50:52

标签: django django-models custom-fields

是否可以创建引用函数或类而不是模型的Django自定义模型字段?

如果你想知道为什么我会想要这个,这里有一个简短的解释,我正试图实现。

基本上我有一个FreightTable模型,用于计算运费的价值,所以应该有方法来做到这一点。但问题是有几种不同的计算方法,FreightTable的每个实例都应按其具体方式计算。

起初我想过使用某种多态来解决这个问题,但是我必须为每个不同的算法创建一个特定的模型,它们也会在DB的不同表中,这对我来说会有什么问题。我也考虑过使用Django Polymorphic,但我听说它并没有很好地扩展,所以它也不是一个好主意。

我的想法是,如果我能在模型场上引用这些不同的算法,我将会有一个优雅而有效的解决方案。

2 个答案:

答案 0 :(得分:5)

  

我的想法是,如果我可以参考这个不同的算法   在模型领域

这是一个好主意,例如:

CALCULATION_TYPES = [(1, 'Normal'), (2, 'Express')]

class FreightTable(models.Model):
     # Normal fields
     calculation_type = models.IntegerField(choices=CALCULATION_TYPES)

     def calc_normal(self):
         pass

     def calc_express(self):
         pass

     def calc_default(self):
         pass

现在,对于每种货运类型,您可以设置计算方法:

ft = FreightType(calculation_type=2)
ft.save()

在您想要显示计算结果的位置,从实例中获取方法,然后调用适当的方法:

call_map = {1: 'calc_normal', 2: 'calc_express'}
ft = FreightTable.objects.get(pk=1)
calculated_value = getattr(ft, call_map(ft.calculation_type))()

答案 1 :(得分:2)

Python类,函数和方法无法被pickle,因此您无法将代码本身存储在数据库中。

你能做的是

1)将完整的虚线路径存储在CharField中的函数中。然后使用zope.dottedname包解析对函数的引用,并调用它。

2)将计算代码作为Python源代码存储在数据库中作为纯文本。然后使用eval()模块通过imp或动态模块导入执行它

我不确定Django是否有内部虚线名称解析器,您可以使用它而不是zope.dottedname。