一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求而且返回Web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . php
不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。html
下面是一個返回當前日期和時間做爲HTML文檔的視圖ajax
from django.shortcuts import render,HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = '<html><body>It is now %s</body></html>' % now return HttpResponse(html)
re_path(r'date/',views.current_datetime),
讓咱們逐行閱讀上面的代碼:數據庫
首先,咱們從 django.shortcuts模塊導入了HttpResponse類,以及Python的datetime庫。django
接着,咱們定義了current_datetime函數。它就是視圖函數。每一個視圖函數都使用HttpRequest對象做爲第一個參數,而且一般稱之爲request。瀏覽器
注意,視圖函數的名稱並不重要;不須要用一個統一的命名方式來命名,以便讓Django識別它。咱們將其命名爲current_datetime,是由於這個名稱可以精確地反映出它的功能。緩存
這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每一個視圖函數都負責返回一個HttpResponse對象。服務器
視圖層,熟練掌握兩個對象:請求對象(request)和響應對象(HttpResponse)cookie
django將請求報文中的請求行、首部信息、內容主體封裝成 HttpRequest 類中的屬性。 除了特殊說明的以外,其餘均爲只讀的。session
''' # 視圖部分 # 請求對象 響應對象 # 瀏覽器發來的是 一堆 字符串 # django 內部是 wsgiref 已經幫咱們處理了 # request 是全部 瀏覽器 發來的 ''' from django.shortcuts import render,HttpResponse import time def index(request): # ================================HttpRequest對象=========================================== print('method:',request.method) # method: GET method: POST print(request.GET) # <QueryDict: {}> <QueryDict: {'name': ['1'], 'age': ['2']}> print(request.GET.get('name')) # None alice print(request.POST) # <QueryDict: {}> <QueryDict: {'name': ['alex'], 'age': ['111']}> print(request.POST.get('name')) # None alex print(request.path) # 請求路徑 端口以後 ?以前 (url: 協議://IP:port/路徑?get請求數據) print(request.get_full_path()) # /index/?a=alice 會把數據也拿到 print(request.body) # b'' b'name=&age=' print(request.encoding) # None print(request.META) # ..... print(request.FILES) # <MultiValueDict: {}> print(request.COOKIES) # {'csrftoken': 'NtrDhwNbXcnTSqmxa7wITT1UqccZYu2Z8ywHdf2rYhyURwdtaOAf702tsLkVfqD7'} print(request.session) # <django.contrib.sessions.backends.db.SessionStore object at 0x0000013FF5E90BE0> print(request.user) # AnonymousUser (用戶認證組件下使用) print(request.is_ajax()) # False #=========================================================================== ctime = time.time() return render(request,'index.html',{'timer':ctime})
# request 屬性
1.HttpRequest.GET 一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。 2.HttpRequest.POST 一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。 POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。 所以,不該該使用 if request.POST 來檢查使用的是不是POST 方法;應該使用 if request.method == "POST" 另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。 注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用: request.POST.getlist("hobby") 3.HttpRequest.body 一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。 可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。 4.HttpRequest.path 一個字符串,表示請求的路徑組件(不含域名)。 例如:"/music/bands/the_beatles/" 5.HttpRequest.method 一個字符串,表示請求使用的HTTP 方法。必須使用大寫。 例如:"GET"、"POST" 6.HttpRequest.encoding 一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。 這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。 接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。 若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。 7.HttpRequest.META 一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例: CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。 CONTENT_TYPE —— 請求的正文的MIME 類型。 HTTP_ACCEPT —— 響應可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。 HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。 HTTP_HOST —— 客服端發送的HTTP Host 頭部。 HTTP_REFERER —— Referring 頁面。 HTTP_USER_AGENT —— 客戶端的user-agent 字符串。 QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。 REMOTE_ADDR —— 客戶端的IP 地址。 REMOTE_HOST —— 客戶端的主機名。 REMOTE_USER —— 服務器認證後的用戶。 REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服務器的主機名。 SERVER_PORT —— 服務器的端口(是一個字符串)。 從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時, 都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_ 前綴。 因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。 8.HttpRequest.FILES 一個相似於字典的對象,包含全部的上傳文件信息。 FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。 注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會 包含數據。不然,FILES 將爲一個空的相似於字典的對象。 9.HttpRequest.COOKIES 一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。 10.HttpRequest.session 一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。 完整的細節參見會話的文檔。 11.HttpRequest.user(用戶認證組件下使用) 一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。 若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。 ------------------------------------------------------------------------------------- 匿名用戶 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點: id 永遠爲None。 username 永遠爲空字符串。 get_username() 永遠返回空字符串。 is_staff 和 is_superuser 永遠爲False。 is_active 永遠爲 False。 groups 和 user_permissions 永遠爲空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引起 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。
# request 方法
1.HttpRequest.get_full_path() 返回 path,若是能夠將加上查詢字符串。 例如:"/music/bands/the_beatles/?print=true" 2.HttpRequest.is_ajax() 若是請求是經過XMLHttpRequest 發起的,則返回True,方法是檢查 HTTP_X_REQUESTED_WITH 相應的首部是不是字符串'XMLHttpRequest'。 大部分現代的 JavaScript 庫都會發送這個頭部。若是你編寫本身的 XMLHttpRequest 調用(在瀏覽器端),你必須手工設置這個值來讓 is_ajax() 能夠工做。 若是一個響應須要根據請求是不是經過AJAX 發起的,而且你正在使用某種形式的緩存例如Django 的 cache middleware, 你應該使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 裝飾你的視圖以讓響應可以正確地緩存。
響應對象主要有三種形式:
HttpResponse()
return HttpResponse('OK-OK')
render()
render(request, template_name[, context])
結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。
參數: request: 用於生成響應的請求對象。 template_name:要使用的模板的完整名稱,可選的參數 context:添加到模板上下文的一個字典。默認是一個空字典。若是字典中的某個值是可調用的,視圖將在渲染模板以前調用它。
render方法就是將一個模板頁面中的模板語法進行渲染,最終渲染成一個html頁面做爲響應體。
redirect()
傳遞要重定向的一個硬編碼的URL
def my_view(request): ... return redirect('/some/url/')
也能夠是一個完整的URL:
def my_view(request): ... return redirect('http://example.com/')
key:兩次請求
1)301和302的區別。 301和302狀態碼都表示重定向,就是說瀏覽器在拿到服務器返回的這個狀態碼後會自動跳轉到一個新的URL地址,這個地址能夠從響應的Location首部中獲取 (用戶看到的效果就是他輸入的地址A瞬間變成了另外一個地址B)——這是它們的共同點。 他們的不一樣在於。301表示舊地址A的資源已經被永久地移除了(這個資源不可訪問了),搜索引擎在抓取新內容的同時也將舊的網址交換爲重定向以後的網址; 302表示舊地址A的資源還在(仍然能夠訪問),這個重定向只是臨時地從舊地址A跳轉到地址B,搜索引擎會抓取新的內容而保存舊的網址。 SEO302好於301 2)重定向緣由: (1)網站調整(如改變網頁目錄結構); (2)網頁被移到一個新地址; (3)網頁擴展名改變(如應用須要把.php改爲.Html或.shtml)。 這種狀況下,若是不作重定向,則用戶收藏夾或搜索引擎數據庫中舊地址只能讓訪問客戶獲得一個404頁面錯誤信息,訪問流量白白喪失;再者某些註冊了多個域名的 網站,也須要經過重定向讓訪問這些域名的用戶自動跳轉到主站點等。
用redirect能夠解釋APPEND_SLASH的用法!
示例:
from django.shortcuts import render,HttpResponse,redirect import time def index(request): #===================================HttpResponse對象======================================== return HttpResponse('OK-OK') return HttpResponse('<h1>哈哈</h1>') return render(request,'index.html') ctime = time.time() return render(request,'index.html',{'timer':ctime}) # def render(request, template_name, context=None, content_type=None, status=None, using=None): # 數據何時變過來得 index 不是html 文件 由於有{} 有模板語法 叫模板文件 # index.html 模板文件 render 找到.html 文件 若是有模板語法 就替換 以後在傳給瀏覽器 # render 真正得 替換成了 完整html 文件 # 第三個參數 加不加 若是.html 有模板語法{{}}就加 第三個參數 return redirect('/some/url') return redirect('http://example.com/')
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {# action 不寫會取,當前頁面. 只寫路徑 /index/ 會用url拼 路徑 #} {#<form action="" method="post">#} <form action="/index/" method="post"> 姓名 <input type="text" name="name"> 年齡 <input type="text" name="age"> <input type="submit"> </form> <p>{{ timer }}</p> </body> </html>