How to store arbitrary name/value key pairs in a Django model?
我有一个固定的数据模型,它有很多数据字段。
1 2 3 4 5 6 | class Widget(Models.model): widget_owner = models.ForeignKey(auth.User) val1 = models.CharField() val2 = models.CharField() ... val568 = ... |
我想通过让我的用户指定自定义数据字段,将更多的数据填充到这个小部件中。明智的做法是什么?将名称/值对存储在用户可以指定其他"小部件字段"的位置是个好主意吗?我的假想如下:
1 2 3 4 5 6 7 8 9 10 | data_types = ('free_text', 'date', 'integer', 'price') class CustomWidgetField(models.Model) owner = ForeignKey(auth.User) field_title = models.CharField(auth.User) field_value_type = models.CharField(choices = data_types) class CustomWidgetValue(models.Model) field_type = ForeignKey(CustomWidgetField) widget = ForeignKey(Widget) value = models.TextField() |
因此,我想让每个用户构建一种新的数据字段类型,它将应用于所有小部件,然后为每个小部件中的每个自定义字段指定值。我可能需要像在本地字段上一样对这些自定义字段进行过滤/搜索(我认为这比在本地字段上操作要慢得多),但规模是每个小部件有几十个自定义字段,每个用户的库存中只有几千个小部件。我也可以将自定义字段上的大部分搜索/筛选批处理到后端脚本中(可能)。
考虑使用序列化dict表示所有自定义属性。我在最近的一个项目中使用了它,它工作得非常好。
1 2 3 4 5 6 7 8 9 10 11 | class Widget(models.Model): owner = models.ForeignKey(auth.User) props = models.TextField(blank=True) # serialized custom data @property def props_dict(self): return simplejson.loads(self.props) class UserProfile(models.Model) user = models.ForeignKey(auth.User) widget_fields = models.TextField(blank=True) # serialized schema declaration |
看起来你已经改造了三重店。我认为这是一件很常见的事情,因为我们遵循数据库灵活性的概念得出了它的自然结论。在关系数据库系统中,三重存储往往效率相当低,但有专门为它们设计的系统。
http://en.wikipedia.org/wiki/triplestore网站
在您所说的范围内,您的性能可能是可以接受的,但是如果没有专门的数据库,它们通常无法很好地扩展。
在我看来,实现这种完全可扩展模型的最佳方法实际上是使用EAV(实体、属性、值)。它基本上是将无模式非关系数据库引入SQL的一种方法。你可以在维基百科(http://en.wikipedia.org/wiki/entity-attribute-value_model)上阅读更多关于它的信息,但在django中更好的实现之一是来自everyblock代码库。希望能帮上忙!
http://github.com/brosner/everyblock_code/blob/master/ebpub/ebpub/db/models.py
http://github.com/tuttle/django-expando可能对您感兴趣。
当我有一个可以完全由用户定制的对象时,我在模型上创建了一个字段,该字段将在列中包含一些JSON。然后,您可以在需要使用或保存它时来回序列化。
但是,它确实使在SQL查询中使用数据变得更加困难。