2009-09-18 64 views
46

我使用Django和Apache來提供網頁。我的JavaScript代碼當前包含一個數據對象,其中的值將根據用戶從選項菜單中選擇而顯示在各種HTML小部件中。我想從Python字典中派生這些數據。我想我知道如何在JavaScript中嵌入JavaScript代碼,但是如何將數據對象嵌入到該腳本中(即時),以便腳本的功能可以使用它?換句話說,我想從Python字典創建一個JavaScript對象或數組,然後將該對象插入到JavaScript代碼中,然後將該JavaScript代碼插入到HTML中。我想這個結構(例如嵌入在JavaScript代碼中的變量中的數據)並不是最理想的,但作爲新手我不知道替代方案。我已經看到了Django序列化函數的書寫,但是直到我可以將數據放入我的JavaScript代碼中,這些功能才幫助我。通過Django傳遞Python數據到JavaScript

我還沒有使用jQuery等JavaScript庫。

+0

[Django的模板變量和Javascript]的可能的複製(http://stackoverflow.com/questions/298772/django-template-variables-and-javascript) – 2016-05-15 16:05:33

回答

69

我建議不要在你的Django模板中放入大量的JavaScript - 它往往很難編寫和調試,特別是當你的項目擴展時。相反,嘗試將所有JavaScript寫入模板加載的單獨腳本文件中,並在模板中僅包含一個JSON數據對象。這可以讓你做一些事情,比如像JSLint這樣運行你的整個JavaScript應用程序,縮小它等等,你可以用一個靜態HTML文件測試它,而不需要依賴你的Django應用程序。使用像simplejson這樣的庫還可以節省編寫單調乏味的序列化代碼的時間。

如果你沒有假設你正在構建一個AJAX應用程序,這可能簡單地這樣做:

在視圖:

from django.utils import simplejson 


def view(request, …): 
    js_data = simplejson.dumps(my_dict) 
    … 
    render_template_to_response("my_template.html", {"my_data": js_data, …}) 

在模板:

<script type="text/javascript"> 
    data_from_django = {{ my_data }}; 
    widget.init(data_from_django); 
</script> 

請注意,數據類型很重要:如果my_data是一個簡單的數字或來自不包含HTML的受控源(例如格式化日期)的字符串,則不需要進行特殊處理d。如果可能有用戶提供的不可信數據,則需要使用類似escapeescapejs過濾器的方式對其進行消毒,並確保JavaScript安全地處理數據以避免cross-site scripting攻擊。

就日期而言,您可能還想考慮如何通過日期。我幾乎總是發現最容易通過他們爲Unix的時間戳:

在Django中:

time_t = time.mktime(my_date.timetuple()) 

在JavaScript中,假設你已經做了一些類似time_t = {{ time_t }}上面的代碼片段的結果:

my_date = new Date(); 
my_date.setTime(time_t*1000); 

最後,請注意UTC - 您希望Python和Django日期函數以UTC交換數據,以避免用戶當地時間的尷尬轉變。

編輯:請注意,JavaScript中的setTime是以毫秒爲單位,而time.mktime的輸出是秒。這就是爲什麼我們需要乘以1000

+0

謝謝。我計劃將JavaScript作爲媒體文件提供,類似於css樣式表。這似乎比將數據嵌入到js中更好,但我必須學習一些JSON,並編寫一些服務器端代碼來處理數據請求。 – chernevik 2009-09-18 19:11:43

+0

聽起來是一個好主意 - 我真的很喜歡這種方法的一件事是,編寫一個返回JSON的Django視圖是很簡單的(如果你經常這樣做,請看django-piston創建REST API),這很容易測試孤立的部分。 – 2009-09-18 21:19:29

+0

我不會無視這個!我只是建立我的寫作和服務JavaScript的知識點,我實際上使用它。我現在計劃使用JSON傳遞元數據以驅動哪些小部件受菜單選項影響,但這需要我學習更多關於創建和訪問javascript數據結構的知識。 – chernevik 2009-09-22 21:47:34

2

這是不理想的。你有沒有考慮過使用django的內置序列化器來傳遞數據爲JSON?

+0

我以爲我在涉及縮略詞之前,先學習一些基礎知識。但是,我似乎可以學習一些JSON,或者從基本元素中構建一個解決方案,一旦我學習了一些JSON,我將會廢除它。 – chernevik 2009-09-18 19:08:23

3

您可以在您的.html模板中包含<script>標籤,然後構建您的數據結構,但對您很方便。模板語言不僅適用於HTML,它還可以執行Javascript對象文字。

保羅是對的:最好使用json模塊創建一個JSON字符串,然後將該字符串插入到模板中。這將最好地處理報價問題,並輕鬆處理深層結構。

1

請參閱相關回復this question。一種選擇是使用jsonpickle在Python對象和JSON/Javascript對象之間進行序列化。它包裝simplejson並處理通常不被simplejson接受的事物。

1

把Java腳本嵌入到Django模板中是而不是總是壞主意。

寧可,因爲這個規則有一些例外。

一切都取決於您的Java腳本代碼網站和功能。

最好有獨立的靜態文件,如JS,但問題是每個單獨的文件需要另一個連接/ GET /請求/響應機制。有時對於小的一個,兩個內碼代碼os JS把這個放到模板中,然後使用django templatetags機制 - 你可以使用在其他模板中;)

關於對象 - 相同。如果你的網站有AJAX構建/ web2.0喜歡 - 你可以達到很好的效果,把一些計數/數學運算到客戶端。如果對象很小 - 嵌入到模板中,如果較大 - 在另一個連接中響應它們以避免用戶掛起頁面。

+0

是的,你已經內置json到Django;)忘記xml:P – bluszcz 2009-09-19 08:48:44

34

對於任何可能遇到問題的人,請確保您在模板中以安全模式呈現您的json對象。您可以手動設置此類似這樣的

<script type="text/javascript"> 
    data_from_django = {{ my_data|safe }}; 
    widget.init(data_from_django); 
</script>