我需要在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