
介紹
一個
視圖函數(類),簡稱視圖,是一個簡單的Python 函數(類),它接受Web請求并且傳回Web響應。
響應可以是一張網頁的HTML内容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖檔。
無論視圖本身包含什麼邏輯,都要傳回響應。代碼寫在哪裡也無所謂,隻要它在你目前項目目錄下面。
除此之外沒有更多的要求了——可以說“沒有什麼神奇的地方”。為了将代碼放在某處,大家約定成俗将視圖放置在項目(project)或應用程式(app)目錄中的名為views.py的檔案中。
視圖示例
下面是一個以HTML文檔的形式傳回目前日期和時間的視圖:
from
讓我們來逐行解釋下上面的代碼:
- 首先,我們從 django.http子產品導入了HttpResponse類,以及Python的datetime庫。
- 接着,我們定義了current_datetime函數。它就是視圖函數。每個視圖函數都使用HttpRequest對象作為第一個參數,并且通常稱之為request。 注意 :視圖函數的名稱并不重要;不需要用一個統一的命名方式來命名,以便讓Django識别它。我們将其命名為current_datetime,是因為這個名稱能夠比較準确地反映出它實作的功能。
- 這個視圖會傳回一個HttpResponse對象,其中包含生成的響應。每個視圖函數都負責傳回一個HttpResponse對象。
Django使用請求和響應對象來通過系統傳遞狀态。
當浏覽器向服務端請求一個頁面時,Django建立一個HttpRequest對象,該對象包含關于請求的中繼資料。然後,Django加載相應的視圖,将這個HttpRequest對象作為第一個參數傳遞給視圖函數。
每個視圖負責傳回一個HttpResponse對象。
FBV和CBV
我們之前寫過的都是基于函數的view,就叫FBV。還可以把view寫成基于類的。
# urls.py中
url(r'^login.html$', views.Login.as_view()),
# views.py中
from django.views import View
class Login(View):
def dispatch(self, request, *args, **kwargs):
print('before')
obj = super(Login,self).dispatch(request, *args, **kwargs)
print('after')
return obj
def get(self,request):
return render(request,'login.html')
def post(self,request):
print(request.POST.get('user'))
return HttpResponse('Login.post')
使用CBV時要注意: 請求過來後會先執行dispatch()這個方法,如果需要批量對具體的請求處理方法,如get,post等做一些操作的時候,這裡我們可以手動改寫dispatch方法,這個dispatch方法就和在FBV上加裝飾器的效果一樣。
Django shortcut functions
Django shortcut functionsdocs.djangoproject.com
django.shortcuts包含“跨越”多個MVC級别的輔助函數和類。本文隻介紹視圖層所使用到方法。
render()
render(request, template_name[, context])結合一個給定的模闆和一個給定的上下文字典,并傳回一個渲染後的 HttpResponse 對象。
其預設的Content-Type标頭設定為application/json。
參數:
request: 用于生成響應的請求對象。
template_name:要使用的模闆的完整名稱,可選的參數
context:添加到模闆上下文的一個字典。預設是一個空字典。如果字典中的某個值是可調用的,視圖将在渲染模闆之前調用它。
content_type:生成的文檔要使用的MIME類型。預設為 DEFAULT_CONTENT_TYPE 設定的值。
status:響應的狀态碼。預設為200。
一個簡單例子:
from django.shortcuts import render
def my_view(request):
# 視圖的代碼寫在這裡
return render(request, 'myapp/index.html', {'foo': 'bar'})
上面例子等同于:
from django.http import HttpResponse
from django.template import loader
def my_view(request):
# 視圖代碼寫在這裡
t = loader.get_template('myapp/index.html')
c = {'foo': 'bar'}
return HttpResponse(t.render(c, request))
redirect()
參數可以是:
- 一個模型:将調用模型的 get_absolute_url() 函數
- 一個視圖,可以帶有參數:将使用 urlresolvers.reverse 來反向解析名稱
- 一個絕對的或相對的URL,将原封不動的作為重定向的位置。
預設傳回一個臨時的重定向;傳遞
permanent=True可以傳回一個永久的重定向。
示例:
你可以用多種方式使用redirect() 函數。
傳遞一個對象(ORM相關)
将調用get_absolute_url() 方法來擷取重定向的URL:
from django.shortcuts import redirect
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object)
傳遞一個視圖的名稱:
def my_view(request):
...
return redirect('some-view-name', foo='bar')
傳遞要重定向到的一個具體的網址:
def my_view(request):
...
return redirect('/some/url/')
當然也可以是一個完整的網址:
def my_view(request):
...
return redirect('http://example.com/')
預設情況下,redirect() 傳回一個臨時重定向。
以上所有的形式都接收一個permanent 參數;如果設定為True,将傳回一個永久的重定向:
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object, permanent=True)
擴充閱讀: 臨時重定向(響應狀态碼:302)和永久重定向(響應狀态碼:301)對普通使用者來說是沒什麼差別的,它主要面向的是搜尋引擎的機器人。
A頁面臨時重定向到B頁面,那搜尋引擎收錄的就是A頁面。
A頁面永久重定向到B頁面,那搜尋引擎收錄的就是B頁面。