如何在django模型中存储任意名称/值密钥对?

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查询中使用数据变得更加困难。