2014-01-14 46 views
-1

我已經閱讀了很多關於在Django中創建和處理表單的文檔,但是我仍然對實現的某些方面感到困惑。具體來說,我無法理解我應該在哪裏處理由表單發送的數據。它是在使用表單模板的視圖還是在另一個視圖上?表單數據在哪裏處理? (Django)

例如,假設有一個單一形式的索引模板:

*index.html* 
{% load url from future %} 
<form action="{% url 'Directories:_results'%}" method="post"> 
Name: <input type="text" name="txtField" /> 
<input type="submit" name="submit" /> 
</form> 

所以現在我認爲我有兩個版本:

#1版(1個視圖):同樣的觀點顯示器和處理表單

def index(request): 
    if request.method == 'POST': # If the form has been submitted... 
     form = dbForm(request.POST) # A form bound to the POST data 
     if form.is_valid(): # All validation rules pass 
      field = form.cleaned_data['txtField'] 
      #doSomething 
    else: 
     form = dbForm() #unbound form 
    return render(request, 'Directories/index.html', {'form': form}) 

#2版(2次):一個視圖中顯示第E型和一個視圖處理表單數據

#the view that creates the form (unbound) 
def index(request): 
    form = dbForm() 
    return render(request, 'Directories/index.html', {'form':form}) 

#the view that handles the data sent during form submission in the index template. 
def results(request): 
    if request.method == 'POST': 
     form = dbForm(request.POST) # A form bound to the POST data 
     if form.is_valid(): # All validation rules pass 
      field = form.cleaned_data['txtField'] 
      #doSomething 
    else: 
     form = dbForm() #unbound form 
    return render(request, 'Directories/index.html', {'form': form}) 

,這裏是我的urls.py:

from django.conf.urls import patterns, url 
from Directories import views 

urlpatterns = patterns('', 
    url(r'^$', views.index, name='_index'), 
    url(r'^results$', views.results, name='_results'),) 

正如你可以看到每一個版本,因此我想進行數據處理不同要知道這些是否是錯誤的,如果兩者都是正確的,那麼哪一個被認爲是最佳實踐。

+1

不知道你爲什麼要問這個,真的。在版本2中,第二個視圖與版本1中的視圖完全相同:那麼版本2中的第一個視圖有什麼意義? –

+0

對於這個過於簡化的示例版本2似乎是多餘的,但是我想了解的是在哪裏處理數據?因此,我沒有試圖強調這個例子本身,而是強調它背後的概念以及哪個版本被認爲是最佳實踐。例如,在一個更復雜的例子中,你必須處理多個表單,每個表單都有多個提交按鈕,與版本1相比,版本2可以更好地分離問題。我相信這取決於你處理的情況,但是我的問題更像是什麼規範 – per7inac1ousQ

回答

2

通常,表單將發佈到它正在顯示的相同視圖。

可以簡化視圖邏輯,像這樣:

def index(request): 
    form = dbForm(data=request.POST or None) 
    if form.is_valid(): # All validation rules pass 
     field = form.cleaned_data['txtField'] 
     #doSomething 
     return redirect(success_url) 
    return render(request, 'Directories/index.html', {'form': form}) 

注意,如果你在成功的表單提交重定向它通常是不錯的,即使你重定向回同樣的觀點。這可以防止用戶刷新頁面時提示「重新發送表單數據」。

你應該看看文檔在模板呈現形式:
https://docs.djangoproject.com/en/dev/topics/forms/#looping-over-the-form-s-fields

如果不渲染領域的錯誤,例如,用戶將永遠不知道問題是什麼。

將發佈到不同視圖的表單的一個示例是,如果您的基本模板具有出現在每個頁面上的「搜索」表單。當您發佈此表單時,您不想回到當前視圖,您想要轉到「搜索結果」視圖。

1

通常,一個視圖對應一個url。此外,相同的網址應顯示錶單並接受提交的表單。有了這個邏輯,你的第一種方法更好。一個視圖顯示並接受該表單。

但是,在某些情況下,顯示窗體的視圖與接受窗體的視圖不同。例如,具有多個表單的頁面。每個表單可以提交到不同的視圖。但是可以實施不同的視圖來處理該網址並顯示這種形式。

0

首先要理解的是,處理表單的視圖通常也是首先顯示錶單的視圖 - ,因爲它必須在出現錯誤時再次顯示錶單

在模板中,你完全採用手工打造的HTML表單。這是不常見的,因爲如果出現錯誤(通常是未填寫的必填字段),您希望再次呈現表單,並且所有已輸入的值都存在,並且出現錯誤消息。 Django的表單呈現({{ form.as_p }}之類)爲你做這件事,如果你像這樣手工編寫HTML,你就不會得到它。其實你的觀點錯過的還有:根據條款上is_valid(),它導致

所以通常認爲做到這些,除了第二件事就明白了:一個成功的POST之後,你總是重定向的更迭頁面,或可能到同一頁面(這將再次顯示一個空表格)。大多數情況下,用戶不會意外地用刷新按鈕重新提交表單。

所以,你的第一個是典型的,除非你還需要在is_valid()的情況下返回ResponseRedirect來完成,而應該呈現更多形式的模板。不需要第二個視圖。

1

沒有什麼錯或者,它取決於你想要做什麼。默認情況下,表單中的數據發送到同一個請求,但你可以將數據發送到不同的觀點,如果這是更方便

在大多數情況下,它通常是簡單的使用了同樣的觀點。使用兩種觀點是好的,如果你正在使用外部工具\程序\無論或者如果你想收緊你的安全性(具有第二視圖只接受用POST數據例如請求等等),但將需要額外的步驟(錯誤處理,成功的重定向)