2011-04-25 57 views
2

我有一個網站其URL看起來像Django的:重複使用重定向代碼失蹤對象

http://www.example.com/NY-2010/

http://www.example.com/NY-2010/location/

http://www.example.com/Washington-2009/

http://www.example.com/Washington-2009/location/

http://www.example.com/Washington-2009/something-else/

等。各種版本(如紐約)有各種頁面(如位置)。我用的URLconf像

url(r'^(?P<edition>[\d]+\-[\w]+)/$', views.home), 
url(r'^(?P<edition>[\d]+\-[\w]+)/location/$', views.location), 

在每一個我不得不獲取當前版本的意見。事實是,如果版本名稱錯誤,我想重定向到最新版本。所以我做點類似

def home(request, edition): 
    try: 
     event = Edition.objects.get(name=edition) 
    except ObjectDoesNotExist: 
     return redirect(home, edition=Edition.latest()) 
    # If event was found I go on here 

def location(request, edition): 
    try: 
     event = Edition.objects.get(name=edition) 
    except ObjectDoesNotExist: 
     return redirect(home, edition=Edition.latest()) 
    # If event was found I go on here 

等等。當然,我想盡量減少一些重複。我能想到的方法有兩種:

  • 使用get_objects_or_404()和自定義的404視圖,或
  • 抽象函數中的公共部分。

這兩種方式的問題是,他們不允許我做一個適當的重定向,即即使視圖被改變,該URL將保持不變。有沒有更好的方法來處理這些重定向?

編輯看來我的問題並不清楚。特別是我不明白我的意思是抽象出一個函數中的共同部分。所以,我可以做的是我下面

def get_edition_or_current(edition): 
    try: 
     event = Edition.objects.get(name=edition) 
    except ObjectDoesNotExist: 
     event = Edition.latest() 
    return event 

def home(request, edition): 
    event = get_edition_or_current(edition) 
    # I go on with a valid event here 

def location(request, edition): 
    event = get_edition_or_current(edition) 
    # I go on with a valid event here 

這樣可以顯示正確的事件的看法,但我無法改變的URL。要更改網址,該視圖必須返回重定向。我無法從get_edition_or_current中設置視圖的返回值。

那麼,Django如何實現get_object_or_404?好吧,這很簡單,它引發了一個Http404異常,並在稍後捕獲它。但是,這當然只適用於Http404異常,因爲Django被指示捕捉它們。

+0

「中的功能抽象的共同部分」?你爲什麼不這樣做?定製404視圖將包含所有重複的邏輯,不是嗎? – 2011-04-25 17:11:57

+0

要更改URL,我必須在視圖中返回重定向。如果我調用'someFunction()',我不能從'someFunction()'中返回一個重定向。我將不得不檢查它的返回值,以防萬一手動返回重定向,這比我現在做的要好。 – Andrea 2011-04-25 17:18:07

+0

@Andrea:「如果我調用someFunction(),我不能從someFunction()中返回重定向」「?好的。我很困惑你認爲你可以通過「抽象函數中的公共部分」來消除什麼「重複」。現在你說你不能這樣做?但在你說的問題上你可以嗎?請澄清。 – 2011-04-25 17:20:31

回答

1

我認爲最簡單的方法是創建一個名爲get_object_or_redirect的新效用函數,與get_object_or_404一樣。您甚至可以從django.shortcuts複製get_object_or_404的內容作爲實現的起點,或者只是提取出上面的內容。

編輯:如註釋中所述,重定向不能通過引發「異常」來完成,所以這實際上不能像get_object_or_404一樣工作。

+0

問題是,get_object_or_404基於異常,我不確定這是否正確。我應該在哪裏找到我提出的例外情況? Django自動捕獲Http404異常,但這是一個特例。 – Andrea 2011-04-25 17:24:06

+0

下面是一個有趣的討論:http://groups.google.com/group/django-users/browse_thread/thread/2d53733b57202dc2/bb9682d1dd5fe5dd?#bb9682d1dd5fe5dd – 2011-04-25 17:40:36

+0

我不確定這是否改變了,但它似乎是django的立場是重定向不是「例外」,所以沒有HttpRedirectException - 你必須從視圖中返回一個HttpRedirect。我想知道是否可以定義自己的重定向異常,然後處理處理HTTP響應的自定義中間件類。中間件實際上並不是很難實現,但我從來沒有試圖處理異常等。另一個想法是實現一箇中間件來處理來自view方法的404錯誤,並在那裏做重定向。 – 2011-04-25 17:42:06

1

經過一番思考,我找到了一個解決方案。這足以

  • 使用get_object_or_404
  • 自定義的404視圖,但直接將其設置爲所需的視圖。而是將其設置爲將重定向發送到正確視圖的視圖。

handler404 = views.error404 

# Inside views 

def error404(request): 
    return redirect(...) 
+0

+1 - 我認爲使用handler404可能是解決您的問題的最佳方案。也爲你的問題+1 - 這是閱讀有趣的! – 2011-04-26 00:03:56

+0

謝謝。畢竟我接受了你的答案,這要歸功於用一些中間件實現Http異常的有趣鏈接。我不確定我最終會使用哪種解決方案,但它確實是一個很好的閱讀。 – Andrea 2011-04-26 00:06:03