如何在Django模型上存储字典?

我需要在Django模型中存储一些数据。 这些数据不等于模型的所有实例。

起初,我想了解这个模型的子类,但我试图保持应用程序的灵活性。 如果我使用子类,每次需要一个新types的对象,我都需要创build一个完整的类,这是不好的。 我也将结束很多子类只存储一对额外的领域。

我真的觉得字典是最好的方法,但是在Django文档中没有关于在Django模型中存储字典的信息(或者我找不到它)。

任何线索?

如果它真的是字典,就像你正在寻找的任意数据一样,你可以使用两层设置,一个是容器模型,另一个是键值对模型。 您将创build容器实例,创build每个键值实例,并将键值实例集与容器实例相关联。 就像是:

class Dicty(models.Model): name = models.CharField(max_length=50) class KeyVal(models.Model): container = models.ForeignKey(Dicty, db_index=True) key = models.CharField(max_length=240, db_index=True) value = models.CharField(max_length=240, db_index=True) 

这不是很好,但它可以让你使用数据库访问/search字典的内部,而咸菜/序列化的解决scheme不会。

如果您不需要通过这些额外的数据进行查询,那么您可以将其作为序列化字典存储。 使用repr将字典转换为string,并eval将string转换回字典。 注意评估词典中没有用户数据,或使用safe_eval实现。

正如Ned所回答的那样,如果你使用字典的方法,你将无法查询“一些数据”。

如果你仍然需要存储字典,那么目前最好的方法是在Marty Alchin的新书Pro Django中logging的PickleField类。 此方法使用Python类属性来pickle / unpickle python对象,只在需要时存储在模型字段中。

这种方法的基础是使用django的contibute_to_class方法dynamic地添加一个新的字段到你的模型,并使用getattr / setattr按需序列化。

我能find的几个在线示例之一就是JSONField的这个定义。

我通过google的4rth结果来到这个post“django store object”

有点晚了,但是Django-picklefield看起来对我来说是个很好的解决scheme。

来自doc的示例:

要使用,只需在您的模型中定义一个字段:

 >>> from picklefield.fields import PickledObjectField >>> class SomeObject(models.Model): >>> args = PickledObjectField() 

并把任何你喜欢的(只要是可以select的)分配给现场:

 >>> obj = SomeObject() >>> obj.args = ['fancy', {'objects': 'inside'}] >>> obj.save() 

另一个干净而快速的解决scheme可以在这里find: https : //github.com/bradjasper/django-jsonfield

为了方便,我复制了简单的说明。

安装

 pip install jsonfield 

用法

 from django.db import models from jsonfield import JSONField class MyModel(models.Model): json = JSONField() 

我并不确定您要解决的问题的性质,但听起来很像Google App Engine的BigTable Expando 。

Expandos允许您在运行时在数据库支持的对象实例上指定和存储附加字段。 引用文件:

 import datetime from google.appengine.ext import db class Song(db.Expando): title = db.StringProperty() crazy = Song(title='Crazy like a diamond', author='Lucy Sky', publish_date='yesterday', rating=5.0) crazy.last_minute_note=db.Text('Get a train to the station.') 

Google App Engine目前支持Python和Django框架。 如果这是expression模型的最佳方式,可能值得研究。

传统的关系数据库模型没有这种列增加的灵活性。 如果你的数据types足够简单,你可以像传统的RDBMS哲学和黑客价值观一样,通过@Ned Batchelder提出的序列化来打破单一列。 然而,如果你必须使用RDBMS,Django模型inheritance可能是一个很好的select。 值得注意的是,它将为每个级别的派生创build一对一的外键关系。

我同意你需要避免将其他结构化数据填充到单个列中。 但是,如果你必须这样做,Django有一个XMLField内置。

在Django snipplets中也有JSONField。

“不等于模型的所有实例”听起来像是一个“无模式数据库”的良好匹配。 CouchDB是该方法的招牌小孩,您可能会考虑这一点。

在一个项目中,我把Django ORM从来没有玩过的几个表移到CouchDB上,我对此很满意。 我使用couchdb-python,没有Django特定的CouchDB模块。 数据模型的描述可以在这里find。 从Django中的五个“模型”到Django中的三个“模型”和一个CouchDB“数据库”的移动实际上略微减less了我的应用程序中的代码总数。

考虑一下,找出每个数据集的共同点,然后定义你的模型。 它可能需要使用子类或不。 代表共性的外键是不可避免的,但是当它们有意义的时候会被鼓励。

将随机数据填充到SQL表中并不聪明,除非它是真正的非关系数据。 如果是这种情况,请定义您的问题,我们可能会提供帮助。

Django-Geo包含一个“DictionaryField”,您可能会发现它有帮助:

http://code.google.com/p/django-geo/source/browse/trunk/fields.py?r=13#49

一般来说,如果您不需要跨数据查询,则使用非规范化的方法来避免额外的查询。 用户设置是一个很好的例子!

如果您正在使用Postgres,则可以使用hstore字段: https ://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#hstorefield。