2010-06-27 89 views
4

我想知道如果它被認爲是好的(特別是在Django中)有一個URL只用於具有副作用的操作,這只是意圖通過POST訪問,而且基本上用戶不可見。比方說,爲使該混凝土的緣故,我有我的網站上一點點的郵件系統,並從他們的收件箱中,用戶應該能夠做到像一堆東西:網址和副作用(Django)

  • 刪除郵件
  • 將郵件標記爲已讀
  • 報告爲垃圾郵件

隨着所有這些事情導致頁面刷新,而是引導回到同一頁面。我想知道如何設計我的網址和視圖。我看到(至少)兩種選擇,我不知道哪一種更習慣。

項1)

具有用於每個操作一個單獨的URL和視圖。因此,/ inbox/delete-message /映射到views.delete_message等等。在每個視圖結束時,它會重定向回到/ inbox /。

我喜歡用這個選項將事情清楚地分開的方式。如果用戶發現自己向/ inbox/delete-message /發送了一個GET請求,那麼會出現一些奇怪的情況(我是否會拋出一個錯誤頁面?默默重定向它們?)。

選項2)

使用相同的URL,並查看每個動作,和具有標識的動作的POST參數。所以我會有一個相當長的收件箱視圖,這將有一堆if語句測試request.POST ['action'] =='delete',或者request.POST ['delete'] =='true'或者其他什麼。

這個選項對我來說不那麼幹淨,但我也覺得它更常見。

Djangonauts會選擇哪一種?還是有另一種選擇比上述任何一種更好?

回答

2

修改後的選項#1是最好的方法。考慮一下:假設我們不是在談論一個Web應用程序,而是在設計一個收件箱類。你最喜歡哪一種,有多種方法(delete_message(),mark_as_spam()等),或者一個大方法(do_stuff(action))?當然你會使用單獨的方法。

每個操作都有一個單獨的URL,每個操作都有獨立的視圖,這是比較可取的。如果你不喜歡最後的重定向,那就不要使用它。相反,有一個render_inbox(request)方法返回一個HttpResponse,並在每個視圖結束時調用該方法。當然,在POST之後重定向是防止雙重行爲的一種好方法,並且始終爲用戶提供一致的URL。

更好的做法可能是使用Ajax來隱藏動作,但涉及更多。

1

我不認爲任何一個選項都有問題,但從性能的角度來看,#2可能更好。發佈操作後,您可以在不重定向的情況下呈現收件箱,因此可以減少HTTP流量。

0

我同意#2是一個更好的方法。

但請注意用不同的方法重載提交<input /> - 如果用戶使用鍵盤輸入並點擊輸入,它不一定會提交您期望的<input />。要麼禁用自動提交輸入,要麼對代碼進行編碼,以便如果有多個提交可以執行的操作,則還有另一個字段來設置操作應該是什麼(例如,「刪除」複選框,它在測試期間一request.POST)

如果用#1去我想說,一個GET到後只能查看應以405(不支持的方法)來滿足 - 或者,做不到這一點,一個404

1

如果您正在編寫Web 2.0消息應用程序,那麼您將使用AJAX調用,並且根本不會加載新頁面。該過程將如下進行:

  1. 用戶單擊[刪除]作爲消息。這個按鈕有一個JavaScript動作綁定到它。此操作執行以下操作:

    i。更改用戶界面以表明發生了某些事情(灰色消息或放置沙漏)。

    ii。發送請求到/ messages/inbox/1234/delete。 (其中1234是指示哪個消息的某個標識符)

    iii。當來自服務器的響應回來時,它應該指示成功或失敗。在當前用戶界面中反映此狀態。例如,成功時刷新收件箱視圖(或者只是刪除已刪除的項目)。

在服務器端,現在您可以爲每個需要的操作(即/ delete,/ flag等)創建一個URL處理程序。

如果要使用更多的RESTful方法,您可以使用HTTP操作本身來指示要執行的操作。因此,不要將delete包含在您的網址中,而應該放在行動中。所以,而不是GET或POST,使用DELETE /messages/inbox/1234。要設置已被閱讀的標誌,請使用SET /messages/inbox/1234?read=true

我不知道在Django實現這個後面的建議有多簡單,但總的來說,利用協議(在這種情況下是HTTP)是一個好主意,而不是通過將你的動作編碼爲網址或參數。