如何在Django模型中存储任意名称/值键对?

时间:2022-06-09 07:37:37

I have a fixed data model that has a lot of data fields.

我有一个固定的数据模型有很多数据域。

class Widget(Models.model):
    widget_owner = models.ForeignKey(auth.User)
    val1 = models.CharField()
    val2 = models.CharField()
    ...
    val568 = ...

I want to cram even more data into this Widget by letting my users specify custom data fields. What's a sane way to do this? Is storing name/value pairs where the user can specify additional "Widget fields" a good idea? My pseudo thoughts are below:

我想让我的用户指定自定义数据字段,从而将更多的数据填充到这个小部件中。什么是理智的做法呢?在用户可以指定附加“小部件字段”的地方存储名称/值对是一个好主意吗?我的伪想法如下:

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()

So I want to let each user build a new type of data field that will apply to all of their widgets and then specify values for each custom field in each widget. I will probably have to do filtering/searching on these custom fields just as I would on a native field (which I assume will be much slower than operating on native fields.) But the scale is to have a few dozen custom fields per Widget and each User will only have a few thousand Widgets in their inventory. I can also probably batch most of the searching/filtering on the custom fields into a backend script (maybe.)

因此,我希望让每个用户构建一种新的数据字段类型,它将应用于所有窗口小部件,然后为每个窗口小部件中的每个自定义字段指定值。我可能需要在这些自定义字段上进行过滤/搜索,就像在本机字段上一样(我认为这比在本机字段上操作要慢得多)。但是规模是每个小部件有几十个自定义字段,每个用户在他们的目录中只有几千个小部件。我还可以将定制字段上的大部分搜索/过滤处理成后端脚本(可能)。

5 个解决方案

#1


21  

Consider representing all custom properties with serialized dict. I used this in a recent project and it worked really well.

考虑用序列化的命令来表示所有自定义属性。我在最近的一个项目中使用了这个,并且效果非常好。

 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

#2


8  

It looks like you've reinvented the triple store. I think it's a common thing, as we follow the idea of database flexibility to its natural conclusion. Triple stores tend to be fairly inefficient in relational database systems, but there are systems designed specifically for them.

看起来你重新发明了三重存储。我认为这是很常见的事情,因为我们遵循数据库灵活性的概念,以得出它的自然结论。在关系数据库系统中,三元存储往往效率非常低,但是有专门为它们设计的系统。

http://en.wikipedia.org/wiki/Triplestore

http://en.wikipedia.org/wiki/Triplestore

At the scales you're talking about, your performance is likely to be acceptable, but they don't generally scale well without a specialized DB.

在您正在讨论的范围内,您的性能可能是可以接受的,但是如果没有专门的DB,它们通常不能很好地伸缩。

#3


2  

In my opinion, the best way to achieve this sort of completely extensible model is really with EAV (Entity, Attribute, Value). Its basically a way to bring a schemaless non-relational database to SQL. You can read a bunch more about it on wikipedia, http://en.wikipedia.org/wiki/Entity-attribute-value_model but one of the better implementation of it in django is from the EveryBlock codebase. Hope it's a help!

在我看来,实现这种完全可扩展模型的最佳方法是使用EAV(实体、属性、值)。它基本上是将无模式的非关系数据库引入SQL的一种方式。您可以在wikipedia上阅读更多关于它的内容,http://en.wikipedia.org/wiki/Entity-attribute-value_model,但是在django中更好的实现之一是来自EveryBlock codebase。希望这是一个帮助!

http://github.com/brosner/everyblock_code/blob/master/ebpub/ebpub/db/models.py

http://github.com/brosner/everyblock_code/blob/master/ebpub/ebpub/db/models.py

#4


1  

http://github.com/tuttle/django-expando may be of interest to you.

您可能对http://github.com/tuttle/django-expando感兴趣。

#5


0  

When I had an object that could be completely customized by users, I created a field on the model that would contain some JSON in the column. Then you can just serialize back and forth when you need to use it or save it.

当我有一个可以被用户完全定制的对象时,我在模型上创建了一个字段,该字段将在列中包含一些JSON。然后,当需要使用或保存时,就可以进行序列化。

However, it does make it harder to use the data in SQL queries.

但是,它确实使在SQL查询中使用数据变得更加困难。

#1


21  

Consider representing all custom properties with serialized dict. I used this in a recent project and it worked really well.

考虑用序列化的命令来表示所有自定义属性。我在最近的一个项目中使用了这个,并且效果非常好。

 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

#2


8  

It looks like you've reinvented the triple store. I think it's a common thing, as we follow the idea of database flexibility to its natural conclusion. Triple stores tend to be fairly inefficient in relational database systems, but there are systems designed specifically for them.

看起来你重新发明了三重存储。我认为这是很常见的事情,因为我们遵循数据库灵活性的概念,以得出它的自然结论。在关系数据库系统中,三元存储往往效率非常低,但是有专门为它们设计的系统。

http://en.wikipedia.org/wiki/Triplestore

http://en.wikipedia.org/wiki/Triplestore

At the scales you're talking about, your performance is likely to be acceptable, but they don't generally scale well without a specialized DB.

在您正在讨论的范围内,您的性能可能是可以接受的,但是如果没有专门的DB,它们通常不能很好地伸缩。

#3


2  

In my opinion, the best way to achieve this sort of completely extensible model is really with EAV (Entity, Attribute, Value). Its basically a way to bring a schemaless non-relational database to SQL. You can read a bunch more about it on wikipedia, http://en.wikipedia.org/wiki/Entity-attribute-value_model but one of the better implementation of it in django is from the EveryBlock codebase. Hope it's a help!

在我看来,实现这种完全可扩展模型的最佳方法是使用EAV(实体、属性、值)。它基本上是将无模式的非关系数据库引入SQL的一种方式。您可以在wikipedia上阅读更多关于它的内容,http://en.wikipedia.org/wiki/Entity-attribute-value_model,但是在django中更好的实现之一是来自EveryBlock codebase。希望这是一个帮助!

http://github.com/brosner/everyblock_code/blob/master/ebpub/ebpub/db/models.py

http://github.com/brosner/everyblock_code/blob/master/ebpub/ebpub/db/models.py

#4


1  

http://github.com/tuttle/django-expando may be of interest to you.

您可能对http://github.com/tuttle/django-expando感兴趣。

#5


0  

When I had an object that could be completely customized by users, I created a field on the model that would contain some JSON in the column. Then you can just serialize back and forth when you need to use it or save it.

当我有一个可以被用户完全定制的对象时,我在模型上创建了一个字段,该字段将在列中包含一些JSON。然后,当需要使用或保存时,就可以进行序列化。

However, it does make it harder to use the data in SQL queries.

但是,它确实使在SQL查询中使用数据变得更加困难。