2017-03-03 35 views
2

這是models.py我的課:(Django)如何將兩個url映射到一個視圖?

class Person(models.Model): 
    name = models.CharField(max_length=64) 
    persnr = models.AutoField(primary_key=True) 

這是我的看法:

def show_person(request, persnr): 
    pers = get_object_or_404(Person, pk=persnr) 
    context={'pers':pers} 
    return render(request, 'company/person.html', context) 

這是我的網址:

url(r'^show_person/(?P<persnr>\d+)', "company.views.show_person", name='show_person'), 

我怎樣才能得到相同的觀點(show_person)與這兩個網址:

server/show_person/(persnr) 

server/show_person/(name) 
+1

是什麼阻止你創建捕獲名稱的另一個網址?除了當然這不會工作,因爲該視圖期待PK,所以目前還不清楚爲什麼你會希望這兩個URL都轉到相同的視圖。 –

+0

我嘗試過,但不知道如何解決與預期pk – Dannad

+0

錯誤,我建議不要使用相同的URL有兩個相同的頁面。你應該選擇一個你喜歡的,然後重定向另一個。例如,將'show_person/123'設置爲'show_person/john-smith'。 – Anonymous

回答

4

一個稍微不同的方法將接受兩個獨立的參數,一個是PK和一個名字:

url(r'^show_person/(?P<persnr>\d+)', "company.views.show_person", name='show_person'), 
url(r'^show_person/(?P<name>\w+)', "company.views.show_person", name='show_person'), 

def show_person(request, persnr=None, name=None): 
    if persnr is not None: 
     pers = get_object_or_404(Person, pk=persnr) 
    elif name is not None: 
     pers = get_object_or_404(Person, name=name) 
    else: 
     raise Http404 
+0

不理解這種方式爲什麼IF語句?:) – marin

+0

或者:'(?P \ d +)'和'def show_person(request,** kwargs):... get_object_or_404(Person,** kwargs)':-) – Udi

2
url(r'^show_person/(?P<persnr>.*)', "company.views.show_person", name='show_person'), 

def show_person(request, persnr): 
    per = Person.objects.filter(Q(name=persnr)|Q(persnr=persnr)).all() 
    context={'pers':pers} 
    return render(request, 'company/person.html', context) 
1

你可以做

pers = get_object_or_404(Person, Q(name=persnr)|Q(persnr=persnr)) 
-2

我認爲這將是更清楚地寫2個網址映射到同一個視圖功能:

url(r'^show_person/(?P<persnr_or_name>\d+)', "company.views.show_person", name='show_person'), 
url(r'^show_person/(?P<persnr_or_name>.*)', "company.views.show_person", name='show_person'), 


def show_person(request, persnr_or_name): 
    if persnr_or_name.isdigit(): 
     pers = get_object_or_404(Person, pk=persnr_or_name) 
    else: 
     pers = get_object_or_404(Person, name=persnr_or_name) 
    context={'pers':pers} 
    return render(request, 'company/person.html', context) 

而且還有一個前提是,你不允許純數字作爲大多數網站的名字。

但對我來說,我preferer:

url(r'^show_person/(?P<persnr_or_name>\d+)', "company.views.show_person", name='show_person_by_pk'), 
url(r'^show_person/(?P<persnr_or_name>.*)', "company.views.show_person", name='show_person_by_name'), 


def show_person_by_pk(request, pk): 
    pers = Person.objects.get_or_404(pk) 
    context={'pers':pers} 
    return render(request, 'company/person.html', context) 

def show_person_by_name(request, name): 
    pers = get_object_or_404(Person, name=name) 
    context={'pers':pers} 
    return render(request, 'company/person.html', context) 

,如果你想來看的代碼可以縮短爲2行。

+0

這裏不需要兩個網址。無論如何,你正在檢查'isinstance'。 '。*'對於'view'來說足夠了。 – itzMEonTV

+0

@itzmeontv如果在URL模塊中定義它們比在視圖模塊中定義更清晰。這就是我在編程時總是喜歡的 - 聲明比漸進更好。 – kxxoling

+0

好。但是'persnr_or_name'會在你聲明這個時候期待。所以在聲明的意義上沒有更多的否定。否則你應該分別執行'persnr'和'name'。另外'(?P \ d +'不會接受任何名字。 – itzMEonTV

相關問題