我需要在Django模型中存储一些数据。这些数据不等于模型的所有实例。如何在Django模型上存储字典?
起初我想到了模型的子类,但我试图保持应用程序的灵活性。如果我使用子类,每次需要新类型的对象时,我都需要创建一个完整的类,这并不好。我最终还会得到很多子类来存储一对额外的字段。
我真的觉得字典是最好的方法,但Django文档中没有关于在Django模型中存储字典的任何内容(或者我找不到它)。
任何线索?
我需要在Django模型中存储一些数据。这些数据不等于模型的所有实例。如何在Django模型上存储字典?
起初我想到了模型的子类,但我试图保持应用程序的灵活性。如果我使用子类,每次需要新类型的对象时,我都需要创建一个完整的类,这并不好。我最终还会得到很多子类来存储一对额外的字段。
我真的觉得字典是最好的方法,但Django文档中没有关于在Django模型中存储字典的任何内容(或者我找不到它)。
任何线索?
如果它真的是你想要的任意数据字典,你可以使用一个两层设置,一个模型是一个容器,另一个模型是键值对。您将创建容器实例,创建每个键值实例,并将键值实例集与容器实例相关联。喜欢的东西:
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)
它不漂亮,但它会告诉你访问/搜索使用DB字典的内部结构,而泡菜/序列化的解决方案不会。
唯一的缺点是会追加一个数据库查询 – 2010-05-07 21:28:56
如果您不需要通过任何这些额外的数据进行查询,那么您可以将它作为序列化字典存储。使用repr
将字典转换为字符串,并使用eval
将字符串转换回字典。注意eval字典中没有用户数据,或使用safe_eval实现。
想一想,找出每个数据集的共同点......然后定义你的模型。它可能需要使用子类或不需要。代表共同性的外键是不可避免的,但是当它们有意义时会被鼓励。
将随机数据填充到SQL表中并不聪明,除非它是真正的非关系数据。如果是这种情况,请定义您的问题,我们可能会提供帮助。
+1:不要随意将Python对象填充到表中。 – 2008-12-31 11:27:09
我不确定你想要解决的问题的性质,但它听起来很奇怪,类似于Google App Engine's 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框架。如果这是表达模型的最佳方式,可能值得研究。
传统的关系数据库模型没有这种列添加灵活性。如果您的数据类型足够简单,您可以通过序列化将传统的RDBMS理念和破解值打破为一列,如@Ned Batchelder提出的那样;然而,如果你的有使用RDBMS,Django模型继承可能是一条路。值得注意的是,它将为每个推导级别创建a one-to-one foreign key关系。
正如Ned所回答的,如果您使用字典方式,您将无法查询“某些数据”。
如果你仍然需要存储字典,那么目前最好的方法是在Marty Alchin的新书Pro Django中记录的PickleField类。此方法使用Python类属性来腌/取消只存储在模型字段中的python对象。
这种方法的基础是使用django的contibute_to_class
方法为您的模型动态添加一个新字段,并使用getattr/setattr进行按需序列化。
我能找到的几个在线例子之一就是JSONField的这个定义。
“不等于模型的所有实例”对我来说听起来像是一个“无模式数据库”的良好匹配。 CouchDB是该方法的招牌小孩,您可能会考虑这一点。
在一个项目中,我将Django ORM从来没有玩过的很多表移到CouchDB上,我对此很满意。我使用couchdb-python,没有任何Django特定的CouchDB模块。数据模型的描述可以在here找到。从Django中的五个“模型”到Django中的三个“模型”和一个CouchDB“数据库”的移动实际上略微减少了我的应用程序中的代码总数。
Django的地理包括“DictionaryField”你可能会发现有用:
http://code.google.com/p/django-geo/source/browse/trunk/fields.py?r=13#49
一般来说,如果你没有需要查询整个数据使用非规范化的做法,以避免额外的查询。用户设置是一个很好的例子!
我来到这个岗位由谷歌的4rth结果“Django的存储对象”
有点晚,但django-picklefield看起来很好的解决方案给我。从文档
例子:
要使用,只是在你的模型中定义一个字段:
>>> from picklefield.fields import PickledObjectField
>>> class SomeObject(models.Model):
>>> args = PickledObjectField()
,并分配任何你喜欢的(只要它是picklable)到外地:
>>> obj = SomeObject()
>>> obj.args = ['fancy', {'objects': 'inside'}]
>>> obj.save()
另一个干净而快速的解决方案可以在这里找到:https://github.com/bradjasper/django-jsonfield
为了方便起见,我复制了简单的说明。
安装
pip install jsonfield
使用
from django.db import models
from jsonfield import JSONField
class MyModel(models.Model):
json = JSONField()
如果您使用的是Postgres,您可以使用hstore场:https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#hstorefield。
“一些数据” - 定义不明确。没有一些数据模型或其他提示,就没有答案。 – 2008-12-31 03:29:32