2010-04-27 109 views
48

我在Appengine上使用Django。我在任何地方都使用django reverse()函數,儘可能使所有內容保持乾燥。Django中的幹網址Javascript

但是,我無法將其應用於我的客戶端JavaScript。有一個JS類根據傳入的ID加載一些數據。有沒有一種標準的方式來不硬編碼這個數據應該來自的URL?

var rq = new Request.HTML({ 
    'update':this.element, 
}).get('/template/'+template_id+'/preview'); //The part that bothers me. 
+1

我很樂意看到的更多討論這個。我也認爲url解析回調太重了。有沒有人在這個主題上找到其他的東西? – 2010-08-11 06:54:12

+0

類似的問題在這裏:http://stackoverflow.com/questions/1795701/django-reverse-for-javascript – 2011-03-09 09:24:50

+0

奇怪我沒有找到那個時候我張貼我的。雖然他們都沒有令人滿意的答案。 – noio 2011-03-22 12:57:50

回答

8

最合理的解決方案似乎是在JavaScript文件中傳遞URL列表,並在客戶端上提供與reverse()等效的JavaScript。唯一的反對意見可能是整個URL結構暴露。

這是一個function(從這個question)。

4

好東西是假設從JavaScript的所有參數,Django會作爲或request.GET中被request.POST傳遞。你可以在大多數情況下這樣做,因爲你不需要用於JavaScript查詢的格式良好的URL。

然後唯一的問題是將url從Django傳遞到JavaScript。我已經爲此發佈了圖書館。示例代碼:

urls.py

def javascript_settings(): 
    return { 
     'template_preview_url': reverse('template-preview'), 
    } 

的javascript

$.ajax({ 
    type: 'POST', 
    url: configuration['my_rendering_app']['template_preview_url'], 
    data: { template: 'foo.html' }, 
}); 
28

還有另一種方法,其不需要露出整個URL結構或AJAX請求用於解決各網址。雖然它不是真的很漂亮,它擊敗其他與簡單:

var url = '{% url blog_view_post 999 %}'.replace (999, post_id); 

blog_view_post網址,不得含有神奇999數本身當然)。

+7

我一直這樣做,感覺有點骯髒,但在這裏看到它讓我覺得更好一點。 – 2013-02-12 07:02:53

+0

請記住URL參數的預期字符類型。如果URL參數接受這個數字,但如果它只需要字母就不行。我也建議使用一些000,因爲它不應該存在(對於一個object.id,至少) – jpimentel 2013-10-22 15:41:43

+1

這很髒。如果你打算在javascript中使用url,最好使它接受GET參數,然後你不需要替換。 GET已經成爲了一個年齡標準,所有的javascript框架都支持傳遞一個數據結構,這個數據結構將被轉換成參數(不像這樣正確地轉義),並且讀得更好。 – dalore 2014-03-21 11:17:19

4

阿納託利的答案相似,但更靈活一點。將在頁面頂部:

<script type="text/javascript"> 
window.myviewURL = '{% url myview foobar %}'; 
</script> 

然後,你可以這樣做

url = window.myviewURL.replace('foobar','my_id'); 

或什麼的。如果您的網址包含多個變量,請多次運行replace方法。

1

我已經找到了這種簡單的伎倆。如果您的網址就像是一個模式:

"xyz/(?P<stuff>.*)$" 

,並要在JS扭轉,而無需實際提供的東西(推遲到JS運行時提供此) - 你可以做到以下幾點:

阿爾特視圖給該參數的默認值 - 沒有的,並處理與錯誤響應,如果它不是設置:

意見。PY

def xzy(stuff=None): 
    if not stuff: 
    raise Http404 
    ... < rest of the view code> ... 
  • 改變URL匹配,使參數可選:"xyz/(?P<stuff>.*)?$"
  • 而且在模板的js代碼:

    阿賈克斯({ 網址:「{{網址意見。 XYZ}}」 + js_stuff, ...... })

生成的模板應該有JS中沒有參數的URL,並且在JS中你可以簡單地連接參數。

2

我喜歡Anatoly的想法,但我認爲使用特定的整數是危險的。我通常希望指定一個對象ID,它總是需要積極的,所以我只是使用負整數作爲佔位符。這意味着將-?到URL定義,像這樣:通過在JavaScript編寫

{% url 'events.views.event_details' event_id=-1 %} 

並使用replace來替換佔位符-1

url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details), 

然後我可以得到相反的URL在模板中,所以,在模板我會寫類似

<script type="text/javascript"> 
var actual_event_id = 123; 
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id); 
</script> 

這很容易地擴展到多個參數o,並且特定參數的映射直接在模板中可見。

+0

其實,我認爲這樣更加危險...... 1)現在URL中允許使用負號,這意味着它可以在你的視圖中傳遞;你需要額外的邏輯來檢查它2)「-1」更可能出現在URL中作爲靜態字符串的一部分而不是「999」。 「999」工作的原因是因爲URL的靜態部分中實際上並不包含「999」。無關緊要,只要它被替換爲不含糊的內容即可。 – user193130 2014-03-24 16:15:17

+1

@ user193130如果它是一個對象ID,那麼您應該可以使用'get_object_or_404' - 最終用戶將會看到相同的404,就好像URL模式不接受負數 – Izkata 2014-07-15 23:48:40

0

我帶來的解決方案之一是在後端生成url並以某種方式將它們傳遞給瀏覽器。

它可能不適合所有情況,但我有一個表(使用AJAX填充),並單擊一行應使用戶從該表中的單個條目。

(我正在使用django-restframeworkDatatables)。

從AJAX的每個條目都貼有網址:

class MyObjectSerializer(serializers.ModelSerializer): 
    url = SerializerMethodField() 
    # other elements 

    def get_url(self, obj): 
     return reverse("get_my_object", args=(obj.id,)) 

上裝載AJAX每個URL連接的數據歸因於行:

var table = $('#my-table').DataTable({ 
    createdRow: function (row, data, index) { 
     $(row).data("url", data["url"]) 
    } 
}); 

和點擊我們使用的URL該數據屬性:

table.on('click', 'tbody tr', function() { 
    window.location.href = $(this).data("url"); 
}); 
8

剛走掙扎,這一點,我想出了一個稍微不同的解決方案。在我的情況下,我想要一個外部的JS腳本來調用一個AJAX調用點擊按鈕(在做一些其他處理之後)。

在HTML,我用這樣的HTML-5自定義屬性

<button ... id="test-button" data-ajax-target="{% url 'named-url' %}"> 

然後,在JavaScript中,壓根兒

$.post($("#test-button").attr("data-ajax-target"), ...); 

這就意味着Django的模板系統做了所有的reverse()邏輯我。

+0

+1這是我在搜索之前考慮的方法爲其他人在做什麼。似乎對我來說是理想的解決方案,除非遺留支持是一個問題。不知道爲什麼這裏沒有更多的牽引力。 – oogles 2016-08-27 22:55:11

+0

這真的很簡單,你的例子正是我想要做的 – 5uperdan 2017-08-11 10:38:53

0

使用這個包:https://github.com/ierror/django-js-reverse

你必須在你的JS對象與Django中定義的所有URL。這是迄今爲止我發現的最好的方法。

你需要做的就是添加生成的JS在你的基地模板的頭部和運行管理命令來更新所產生的JS每次你添加一個網址唯一