2009-12-12 65 views
2

我正在開發一個Web應用程序,用戶可以在其中創建多個相關元素,然後將這些元素保存到數據庫。 Web應用程序不知道數據庫中的主鍵是什麼,因此它爲每個元素分配一個UUID。這些UUID與數據庫中的每個元素一起保存。當Web應用程序將數據發送到Web服務器以放入數據庫時​​,它會使用JSON對所有內容進行編碼。 JSON然後由網絡服務器使用serializers.deserialize('json', DATA)進行反序列化。但是,某些模型具有外鍵,這些外鍵在JSON有效內容中發送,作爲對關聯元素的UUID的引用而不是數據庫ID。例如,我們可具有一個簡單的鏈接對象:如何在Django的模型中添加臨時字段?

class Link(models.Model): 
    uuid = models.CharField(max_length=32) 
    source = models.ForeignKey(Node, related_name='source') 
    target = models.ForeignKey(Node, related_name='target') 

如果源有值的2的ID和目標具有值12的ID,這將被序列化到JSON作爲這樣的:

{"uuid": "[some long uuid]", 
"source": 2, 
"target": 12} 

然而,因爲在這種情況下,我們不知道的源和目標的數據庫ID,可能是因爲他們尚未設置,我所能做的最好的是通過在UUID是這樣的:

{"uuid": "[some long uuid]", 
"sourceuuid": "[uuid of source]", 
"targetuuid": "[uuid of target]"} 

不幸的是,th當我撥打serializers.deserialize的數據時,引發了FieldDoesNotExist: Link has no field named u'sourceuuid'的例外。

我想找到一種方法,我可以通過UUID進入,然後讓數據庫填入ID,一旦它保存了適當的部分或在必要時查找它們。我不想將sourceuuidtargetuuid保存在數據庫中,因爲保存整數的空間較少,並且指示速度也應該更快。

所以,我正在尋找的是一個臨時的領域。一個我可以實例化並引用,但永遠不會保存回數據庫。任何想法,我會如何創造這樣的事情?

更新與更多的澄清

感謝您的幫助,到目前爲止,我知道,他們是Python對象,我可以指定任意字段的對象。但是,問題是serializers.deserialize('json', INDATA)會引發錯誤。

僅供參考下面是JSON的一個大塊的解串器喜歡,它有外鍵用自己的ID:

ser='''[{"pk": 1, "model": "myapp.link", 
     "fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", 
        "source": 2, 
        "target": 12}}]''' 
serializer.deserialize('json',ser) 

不過,我可以提供的是:

ser='''[{"pk": 1, "model": "myapp.link", 
     "fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", 
        "sourceuuid": "11111111-2222-3333-4444-555555555555", 
        "targetuuid": "66666666-7777-8888-9999-000000000000"}}]''' 
serializer.deserialize('json',ser) 
FieldDoesNotExist: Link has no field named u'sourceuuid' 

原因我需要虛擬場是一個實際的領域,因爲deserialize需要實際的領域。

回答

1

你可以定義一個外鍵給非物化django模型,它存儲你需要的信息。

要做到這一點,在新的模型的外鍵(或OnetoOne密鑰)的定義,只需將

class _meta: 
    managed = False 
+0

這是最接近的,但不是你所期望的。一個到非物化Django模型的ForeignKey仍然在引用表中添加一列。但是,如果我使用'sourceuuid'和'targetuuid'作爲新字段創建一個完整的非物化子類,我可以到某處。我在一個新的'LinkJSON'類中反序列化,然後映射UUID,然後將這些字段複製到'Link'類。它不漂亮,但它有點不錯。如果Python有一個簡單的方法將類型轉換爲基類,那將會更好。 – Pridkett 2009-12-12 14:50:07

+0

我接受這個答案,因爲它最接近我想要做的。我不得不做一些時髦的子類化,然後創建一個JSONSerializer的子類來處理所有事情,但它現在起作用了。不幸的是,它成爲一個非常具體的解決方案,所以我不能將它的全部內容發佈到StackOverflow。 – Pridkett 2010-01-04 19:48:05

0

我不知道這樣的臨時領域。這將是很好:)

但我的建議是這樣的:在接收JSON並使其成爲對象的視圖中,您檢查屬性。您只創建一個對象,只有「真實」屬性(不是外鍵或M2M)。你可以爲它們分配任意的屬性(instance.arbitrary_attribute = something),但你不會得到漂亮的查找機制(Model.objects.filter(...))。創建所有對象後,再次循環對象,並且爲每個FK查找具有鏈接的UUID的對象,並鏈接到它(使用instance.id)。

+0

我試圖避免去用JSON所有muckity渣土。這是我可以在代碼中引入錯誤和問題的另一個地方。它會工作,但它是一個混亂的最後手段。 – Pridkett 2009-12-12 14:53:28

0

你可以嘗試創建普通的python屬性,它們不會保存到數據庫。喜歡:

class Link(models.Model): 
    sourceuuid = None 
+0

查看我的更新以獲得澄清。 'deserializer'方法拒絕處理任何不是'Field'的數據。所以這個方法會拋出一個異常。 – Pridkett 2009-12-12 14:51:00

2

我不確定你到底想要做什麼。但請記住,Django模型只是Python對象 - 而Python對象完全是動態的。因此,即使在模型上沒有定義uuid字段,obj.uuid = whatever也是完全有效的。

+0

我已經更新了一些更詳細的問題。我需要它是一個實際的'Field',否則'deserialize'會拋出一個異常。 – Pridkett 2009-12-12 14:51:47

0

爲什麼不直接使用UIDS作爲主鍵?

集primary_key爲True

class Node(models.Model): 
    uuid = models.CharField(max_length=32, primary_key=True) 
    [...] 


class Link(models.Model): 
    uuid = models.CharField(max_length=32, primary_key=True) 
+0

我已經想過,如果我找不到另一種方式,那就是我可能做的。但是,UUID在數據庫中佔用更多的空間,並且比索引搜索和搜索要慢。 – Pridkett 2009-12-12 18:16:38

+0

這是很不清楚你想要做什麼..也許如果你帶來更多的細節關於你的任務會有一個很好的解決方案 – 2009-12-12 18:47:27

相關問題