2013-04-20 51 views
1

我正在爲我的Django應用程序(普通Django 1.4,而不是非Rel版本)上運行的圖像上傳功能在Google App Engine上運行。上傳的圖像被包裝在一個Django模型中,該模型允許用戶添加標題和搜索標籤等屬性。更多Blobstore上傳與標準Django困境

上傳是通過函數調用blobstore.create_upload_url(url)創建一個Blob存儲上傳的URL進行。函數參數是上傳完成後Bobstore重定向到的url。我希望這是默認的Django表單處理程序的url,它執行包裝圖像的模型的保存/更新,所以我不必複製表單驗證,錯誤報告和數據庫更新的默認Django行爲。

我試着提供reverse('admin:module_images_add')create_upload_url()但這不起作用,因爲它拋出一個[Errno 30] Read-only file system exception。我認爲這起源於默認的Django表單處理程序,它再次嘗試以標準的Django方式上傳文件,但後來碰到了不允許訪問文件系統的Google App Engine磚牆。

此刻,我可以看到得到這個工作,而無需複製代碼的唯一途徑就是通過嚴格分離的過程:一個用於定義圖像模型實例,第二個用於上載的實際圖像。不是很直觀。

另請參閱我之前發佈的this question and answer

有關如何使用一個表單並重用Django默認表單處理程序來獲得此工作的任何建議?

編輯:

我一直在閱讀了關於裝飾(我是比較新的蟒蛇),並從我讀,裝飾似乎能夠修改現有的Python代碼的行爲。是否有可能改變現有表單處理程序的運行時行爲,以使用裝飾器解決上述問題?我顯然必須(1)開發裝飾器並(2)將其附加到默認處理程序。我不確定(2)是否可行,因爲它必須在運行時完成。我不能修補在GAE上運行的Django代碼...

回答

1

嗯,我終於設法讓這個工作。這是我做的情況下,任何人都跑進這個問題,以及:

(1)我從模型中移除的ImageFile屬性。它最終導致Django嘗試從GAE中不允許的文件系統進行文件上傳。

(2)I加入Blobstore鍵到我的模型,該模型基本上是關鍵GAE BLOBSTORE blob和被要求能夠在稍後的階段,以服務圖像。請注意:使用GAE SDK此屬性的長度有限,但GAE生產時間要長得多。我最終爲它定義了一個TextField

(3)this question使用​​與丹尼爾·羅斯曼的適應,並添加BlobstoreFileUploadHandler到文件處理程序在你的SETTINGS.PY。它將確保Blobstore密鑰存在於請求中,以便與模型保存在一起。

(4)我創建其含有ImageField名爲「圖像」的自定義管理形式。這是必需的,因爲它允許你選擇一個文件。 ImageField實際上是「虛擬」的,因爲它在表單上的唯一目的是允許我選擇要上傳的文件。根據(1),這是至關重要的。

(5)我重寫了render_change_form()我的ModelAdmin類的方法,它將準備一個Blobstore上傳url。上傳網址有兩個版本:一個用於添加新圖像,另一個用於保存現有的更改。上傳網址通過上下文對象傳遞給模板。

(6)我修改了change_form.html以包括Blob存儲上傳從(5)的形式的操作URL。

(7)我重寫了我的ModelAdmin的save_model()方法:

def save_model(self, request, obj, form, change): 
    if request.FILES.has_key("blobkey"): 
     blob_key = request.FILES["blobkey"].blobstore_info._BlobInfo__key 
     obj.blobstore_key = blob_key 
    super(PhotoFeatureAdmin, self).save_model(request, obj, form, change) 

這讓我找回Blob鍵由上傳處理程序中設置並將其設置爲我的模型的屬性。

對於圖像模式的缺失,我添加了由模型的刪除信號觸發的特殊功能。這將使Blobstore與應用程序中的圖像模型保持同步。

就是這樣。上述允許上傳圖片到GAE的團塊存儲,其中每個斑被整齊地纏繞在一個Django模型對象,它管理員用戶可以維護。好在是,有沒有必要重複的標準Django的行爲和形象的模型對象可以很容易地在將來的屬性擴展。

最後一句話:在我看來,對於斑點平原的Django在GAE上的支持,目前很低考慮以上。實現這一點應該容易得多,而不必依賴Django的非相對代碼和一長串修改;或者谷歌應該在他們的開發者文件中說明這件事。除非我錯過了某些東西,否則這是無證的領土。