想在我們有兩個視圖:
def thinkingview(request):
user = request.user
if request.method == 'GET':
return render(request, 'think.html', {'user': user})
elif request.method == 'POST:
user = request.user
data_form = ThinkingForm(request.POST)
if data_form.is_valid():
data_form.save()
return redirect('index')
else:
return render(request, 'think.html', {'user': user, 'error': data_form.errors})
def questionview(request):
user = request.user
if request.method == 'GET':
user = request.user
return render(request, 'question.html', {'user': user})
elif request.method == 'POST:
data_form = QuestionForm(request.POST)
if data_form.is_valid():
data_form.save()
return redirect('index')
else:
return render(request, 'question.html', {'user': user, 'error': data_form.errors})
這兩個視圖非常相似凿滤,GET渲染頁面并預(yù)置用戶信息米愿,POST提交文本數(shù)據(jù)威始,不同的只有tamplate和form這兩個對象≈鲁叮現(xiàn)在把這兩個對象抽象出來肤寝,創(chuàng)建一個通用的視圖:
# view.py
def reportview(request, tamplate_name, form):
user = request.user
if request.method == 'GET':
user = request.user
return render(request, tamplate_name, {'user': user})
elif request.method == 'POST:
data_form = form(request.POST)
if data_form.is_valid():
data_form.save()
return redirect('index')
else:
return render(request, tamplate_name, {'user': user, 'error': data_form.errors})
通過URLconf的傳遞額外參數(shù)的方式來傳遞這兩個對象:
# urls.py
from django.conf.urls import url
from myapp import forms, views
urlpatterns = [
url(r'^thinking/$', views.report, {'tamplate_name': 'thinking.html', 'form': forms.ThinkingForm}),
url(r'^question/$', view.report, {'tamplata_name': 'question.html', 'form': forms.QuestionForm})
這樣就有了一個可復(fù)用的、與對象無關(guān)的視圖(在URLconf中甚至可以傳遞model)抖僵!如果再有類似功能的視圖時就可以重用這個report視圖鲤看,而不需要再寫視圖代碼。
現(xiàn)在來做一些優(yōu)化耍群,在同一個視圖函數(shù)中對POST
和GET
進(jìn)行處理是一種比較粗糙的做法义桂,一個比較好的設(shè)計(jì)習(xí)慣應(yīng)該是,用兩個分開的視圖函數(shù)——一個處理POST請求世吨,另一個處理GET請求澡刹,然后在相應(yīng)的地方分別進(jìn)行調(diào)用。
寫一個分發(fā)函數(shù)耘婚,由它來分派GET和POST請求:
#views.py
from django.views.decorators.http import require_http_methods
...
def method_splitter(request, *args, **kwargs):
#對http method進(jìn)行分發(fā)
get_view = kwargs.pop('get', None)
post_view = kwargs.pop('post', None)
if request.method == 'GET' and get_view is not None:
return get_view(request, *args, **kwargs)
elif request.method == 'POST' and post_view is not None:
return post_view(request, *args, **kwargs)
raise Http404
@require_http_methods('GET')
def report_get(request, tamplate_name):
user = request.user
return render(request, tamplate_name, {'user': user})
@require_http_methods('POST')
def report_post(request, tamplate_name, form):
data_form = form(request.POST)
if data_form.is_valid():
data_form.save()
return redirect('index')
else:
return render(request, tamplate_name, 'user': request.user, 'error': data_form.errors})
#urls.py
urlpatterns = [
url(r'^thinking/$', views.report, {'tamplate_name': 'thinking.html', 'form': forms.ThinkingForm, 'get': view.report_get, 'post': view.report_post}),
url(r'^question/$', view.report, {'tamplata_name': 'question.html', 'form': forms.QuestionForm, 'get': view.report_get, 'post': view.report_post})
現(xiàn)在我們就擁有了一個不錯的,可以通用的視圖函數(shù)了陆赋,里邊封裝著由request.method
的返回值來分派不同的視圖的程序.