2012-03-27 63 views
6

PK/ID來訪問我的網站上一個項目的詳細信息頁面中,應當使用下面的網址URL設計:方法來隱藏URL

<mydomain>/item/1 

其中1是該項目的主鍵

我要尋找一個解決方案,讓我重新設計符合下列要求的網址:

  • 排除PK或從URL任何順序ID
  • 能夠唯一訪問項目的詳細信息頁面

我打算問這是一個普通的網頁設計問題,但只是想我應該提到我正在使用Python/Django。

+1

slugfield是個不錯的選擇! – dm03514 2012-03-27 21:10:58

回答

6

你需要有一些樣的URL標識,而這個標識:

  1. 必須是唯一的(沒有兩個對象可以有相同的ID)
  2. 必須是永久性的(標識對於一個對象絕對不能改變)

所以沒有那麼多的選項,而對象的主鍵是最好的選擇。如果由於某種原因,你不能使用它(爲什麼不?),你可以編碼或混淆它:請參閱this question及其答案,瞭解如何做到這一點的一些想法。

Stack Overflow自己的URL設計值得一看。您可以通過表單

https://stackoverflow.com/questions/9897050/any-text-you-like-here!

這使URL包含關鍵字從問題的職稱(搜索引擎),同時還能夠更改標題的變化時的任何URL達到這個問題而不會破壞舊的鏈接。

+0

謝謝Gareth。你的回答爲我提供了很好的方向,我隱約想到了什麼。我不想在url中使用自動生成的pk的原因是因爲我不希望外人能夠弄清楚在網站上創建了多少物品。以下是您的後續問題。堅持使用自動生成的pk並採用編碼/混淆解決方案,還是設計和使用函數來生成不連續的pk會更好嗎?謝謝。 – tamakisquare 2012-03-27 21:32:07

+3

堅持數據庫中自動生成的主鍵,並使用URL中的編碼。 (如果你在URL中進行編碼,如果你發現有問題,你總是可以選擇在將來更改編碼方案,但是如果你在數據庫中這樣做很難改變。) – 2012-03-27 21:37:35

+0

這是一個很好的觀點。再次感謝。 :) – tamakisquare 2012-03-27 22:02:24

4

那麼有很多方法可以做到這一點。由於您使用的是django,請查看SlugField。或者您生成UUID並將其存儲在每個項目上以供訪問。

4

對於Django,您可以給模型SlugField,然後讓視圖使用它查找模型。

MyModel.objects.filter(slug_field_name='some-slug-value') 

確保某種形式的唯一性約束在其上。

0

這樣做的一個骯髒的方法是使用cookie來保存被請求的對象的id。我並不特別喜歡這個想法,除非您有經驗編寫/擴展框架,否則獲得支持框架可能非常困難。

某些框架支持使用id =屬性而不是URL路徑。如果將它作爲POST參數包含在內,則它將不可見,但將POST與POST鏈接在一起將具有挑戰性,因爲它旨在提交表單數據。

我建議的方法是使用除ID之外的東西來唯一標識您的對象,如果這是真實的需求。然後將其包含在您的網址中。儘管從數據庫的角度來看這不是一個理想的設計,但它確實有好處。首先,您必須考慮爲什麼要隱藏這些信息。如果是出於搜索引擎優化的目的,使用該項目的名稱而不是它的ID是你想要的URL。真正的問題是,如果您只是將這些信息隱藏在其他數據通道中,那麼您將擁有不同資源的相同URL。由於許多原因,這不亞於SEO和用戶書籤。使用人類可讀的密鑰可以解決這兩種情況和其他問題,同時激怒您的DBA。使用這種方法也應該可以直接或通過使用控制器中的其他代碼進行翻譯,從而輕鬆地進入框架,以便進行翻譯,這可能會使DBA設置正確。

5

我不喜歡slugfield選項,因爲它將額外的查詢添加到數據庫。

我做了一個項目如下:

我的URL看起來像這樣:

<domain>/item/5927/728e26e9464a171b228bc9884ba3e4f76e2f8866/ 

這就是:

<domain>/item/<id>/<hash>/ 

如果你不知道的哈希你可以」 t到物品:

urls.py:

url(r'^item/(?P<id>\d+)/(?P<hash>\w+)/$', 'rwapp.views.item', name='item') 

views.py:

from hashlib import sha1 

def item(request,id=None,hash=None): 
    if not id: 
     return HttpResponseRedirect("/home") 
    if hash: 
     chash = sha1("secret_word%s"%id).hexdigest() 
     if not chash==hash: 
      return HttpResponseRedirect("/home") 
    else: 
     return HttpResponseRedirect("/home") 

當然,每次渲染你必須添加//部分的URL時間。