django views視圖
視圖函數簡稱視圖,本質上是一個簡單的python函數,它接受web請求並且返回web響應;響應的內容可以是HTML網頁、重定向、404錯誤、XML文檔或圖像等任何東西,但是,無論視圖本身是個什麽處理邏輯,最好都返回某種響應
視圖函數的代碼寫在哪都無所謂,只要它在你的python目錄下面,但是通常我們約定將視圖放置在項目或應用程序目錄中的名為views.py的文件中。
1、一個簡單的視圖
下面是一個返回當前日期和時間作為HTML文檔的視圖:
from django.http import HttpResponse import datetime def current_datetime(request): now= datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
讓我們逐行分析一下上面的代碼:
首先,從django.http模塊導入了HttpResponse類,以及python的datetime庫
接著,我們定義了current_datetime視圖函數
每個視圖函數都接收一個HttpRequest對象作為第一位置參數,一般取名為request,你可以取別的名字,但這不符合潛規則,最好不要那麽做
視圖函數的名稱沒有強制規則,但盡量不要和python及django內置的各種名稱重名,並且盡量精確地反映出它的功能,比如這裏的current_datetime
該視圖返回一個HttpResponse對象,其中包含生成的HTML頁面。
2、返回錯誤
在django中返回http錯誤代碼是非常簡單的;HttpResponse的許多子類對應著除了200(代表OK)以外的一些常用的http狀態碼。
為了標識一個錯誤,可以直接返回那些子類中的一個實例,而不是普通的HttpResponse,想下面這樣:
from django.http import HttpResponse, HttpResponseNotFounddef my_view(request): # ... if foo: return HttpResponseNotFound(‘<h1>Page not found</h1>‘) else: return HttpResponse(‘<h1>Page was found</h1>‘)
django為404錯誤提供了一個特化的子類HttpResponseNotFound;由於一些狀態碼不太常用,所以不是每個狀態碼都有一個特化的子類。
也可以向HttpResponse的構造器傳遞HTTP狀態碼,來創建你想要的任何狀態碼的返回類,像下面這樣:
from django.http import HttpResponse def my_view(request): # ... # Return a "created" (201) response code. return HttpResponse(status=201)
關鍵是在返回中提供status=201參數,別的什麽303之類的錯誤都可以參照上面的例子。
3、Http404異常
class django.http.Http404
這是一個django內置的異常類,可以在需要的地方彈出它,django會捕獲它,並且帶上HTTP404錯誤碼返回你當前APP的標準錯誤頁面或者自定義錯誤頁面,像下面這樣:
from django.http import Http404 from django.shortcuts import render from polls.models import Poll def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404("Poll does not exist") return render(request, ‘polls/detail.html‘, {‘poll‘: p})
為了在django返回404時顯示自定義的HTML,可以創建要給名為404.html的HTML模版,並將其放置在模版樹的頂層,當DEBUG設置為False時,此模版將被自動使用,當DEBUG為True時,可以向Http404提供消息,它將顯示在標準的內置404調試模版中,可以使用這些消息進行調試。
4、Django內置的快捷方法
django在django.shortcuts模塊中,為我們提供了很多快捷方便的類和方法,它們都很重要,使用頻率很高。
(1)render()
render(request,template_name,context=None,content_type=None,status=None,using=None)
結合一個給定的模版和一個給定的上下文字典,返回一個渲染後的HttpResponse對象。
必須參數:
- request:視圖函數處理的當前請求,封裝了請求頭的所有數據,其實就是視圖參數request
- template_name:要使用的模版的完整名稱或者模版名稱的列表,如果是一個列表,將使用其中能夠查找到的第一個模版
可選參數:
- context:添加到模版上下文的一個數據字典,默認是一個空字典,可以將需要提供給模版的數據以字典的格式添加進去,這裏有個小技巧,使用python內置的locals()方法,可以方便的將函數作用於內的所有變量一次性添加
- context_type:用於生成的文檔的MIME類型,默認為DEFAULT_CONTENT_TYPE設置的值
- status:響應的狀態碼,默認為200
- using:用於加載模版使用的模版引擎的NAME
示例:
下面的示例將渲染模版myapp/index.html,MIME類型為application/xhtml+xml:
from django.shortcuts import render def my_view(request): # View code here... return render(request, ‘myapp/index.html‘, { ‘foo‘: ‘bar‘, }, content_type=‘application/xhtml+xml‘)
與下面的示例效果一樣:
from django.http import HttpResponse from django.template import loader def my_view(request): # View code here... t = loader.get_template(‘myapp/index.html‘) c = {‘foo‘: ‘bar‘} return HttpResponse(t.render(c, request), content_type=‘application/xhtml+xml‘)
(2)redirect()
redirect(to,permanent=False,args,*kwargs)
根據傳遞進來的URL參數,返回HttpResponseRedirect
參數to可以是:
- 一個模型,將調用模型的get_absolute_url()函數,反向解析出目的url
- 視圖名稱,可能帶有參數:reverse()將用於反向解析url
- 一個絕對的或相對的URL:將原封不動的作為重定向的目標位置
默認情況下是臨時重定向,如果設置permanent=True將永久重定向。
示例:
調用對象的get_absolute_url()方法來重定向URL:
from django.shortcuts import redirect def my_view(request): ... object = MyModel.objects.get(...) return redirect(object)
傳遞視圖名,使用reverse()方法反向解析url:
def my_view(request): ... return redirect(‘some-view-name‘, foo=‘bar‘)
重定向到硬編碼的URL:
def my_view(request): ... return redirect(‘/some/url/‘)
也適用於完整的URL:
def my_view(request): ... return redirect(‘https://example.com/‘)
所有上述形式都接受permanent參數,如果設置為true將返回永久重定向:
def my_view(request): ... object = MyModel.objects.get(...) return redirect(object, permanent=True)
(3)get_object_or_404()
get_object_or_404(klass,*args,**kwargs)
這個方法非常有用,常用於查詢模型對象,找到則進行下一步處理,如果未找到則給用戶返回404頁面
在後臺,django其實是調用了模型管理器的get()方法,只是返回一個對象,不同的是,如果get()發生異常,會引發Http404異常,從而返回404頁面,而不是模型的DoesNotExist異常。
必需參數:
klass:要獲取的對象的model類名或者QuerySet等
**kwargs:查詢的參數,格式應該可以被get()接受
示例:
從MyModel中使用主鍵1來獲取對象:
from django.shortcuts import get_object_or_404 def my_view(request): my_object = get_object_or_404(MyModel, pk=1)
上面的例子同下面一樣:
from django.http import Http404 def my_view(request): try: my_object = MyModel.objects.get(pk=1) except MyModel.DoesNotExist: raise Http404("No MyModel matches the given query.")
除了傳遞model名稱,還可以傳遞一個QuerySet實例:
queryset = Book.objects.filter(title__startswith=‘M‘) get_object_or_404(queryset, pk=1)
上面的示例不夠簡潔,因為它等同於:
get_object_or_404(Book, title__startswith=‘M‘, pk=1)
但是如果你的queryset來自其他地方,它就會很有用了
還可以使用manager,如果你自定義了管理器,這將很有用:
get_object_or_404(Book.dahl_objects, title=‘Matilda‘)
還可以使用related managers:
author = Author.objects.get(name=‘Roald Dahl‘) get_object_or_404(author.book_set, title=‘Matilda‘)
與get()一樣,如果找到多個對象將引發一個MultipleObjectsReturned異常。
(4)get_list_or_404()
get_list_or_404(klass,*args,**kwargs)
這其實就是get_object_or_404多值獲取版本;在後臺,返回一個給定模型管理器上的filer()的結果,並將結果映射為一個列表,如果結果為空則彈出Http404異常
必需參數:
klass:獲取該列表的一個model、manager或QuerySet實例
**kwargs:查詢的參數,格式應該可以被filter()接受
示例:
下面的示例從mymodel中獲取所有發布出來的對象:
from django.shortcuts import get_list_or_404 def my_view(request): my_objects = get_list_or_404(MyModel, published=True)
上面的例子同下面一樣:
from django.http import Http404 def my_view(request): my_objects = list(MyModel.objects.filter(published=True)) if not my_objects: raise Http404("No MyModel matches the given query.")
5、HttpRequest對象
每當一個用戶請求發送過來,django將http數據包中的相關內容,打包成為一個HttpRequest對象,並傳遞給視圖函數作為第一個位置參數,也就是reques,視圖函數負責返回一個HttpResponse對象
HttpRequest和HttpResponse對象定義在django.http模塊中
(1)屬性
HttpRequest對象的大部分屬性是只讀的,除非特別註明
- HttpRequest.scheme:字符串類型,表示請求的協議種類,如:‘http‘或‘https’
- HttpRequest.body:bytes類型,表示原始HTTP請求的正文,它對於處理非HTML形式的數據非常有用,二進制圖像、XML等,如果要處理常規的表單數據,應該使用HttpRequest.POST;還可以使用類似讀寫的方式從HttpRequest中讀取數據,參見HttpRequest.read()
- HttpRequest.path:字符串類型,表示當前請求頁面的完整路徑,但是不包括協議名或域名;例如:“、music/bands/the_beatles”。這個屬性常被用於我們進行某項操作時,如果不通過,返回用戶先前瀏覽的頁面
- HttpRequest.path_info:在某些web服務器配置下,主機名後的URL部分被分成腳本前綴部分和路徑信息部分;path_info屬性將始終包含路徑信息部分,不論使用的web服務器是什麽,使用它代替path可以讓代碼在測試和開發環境中更容易地切換。
- HttpRequest.method:字符串類型,表示請求使用的HTTP方法,默認為大寫,像這樣:
if request.method == ‘GET‘: do_something() elif request.method == ‘POST‘: do_something_else()
通過這個屬性來判斷請求的方法,然後根據請求的方法不同,在視圖中執行不同的代碼。
- HttpRequest.encoding:字符串類型,表示提交的數據的編碼方式(如果為None則表示使用DEFAULT_CHARSET設置)。這個屬性是可寫的,可以通過修改它來修改表單數據的編碼,任何隨後的屬性訪問(如GET或POST)將使用新的編碼方式
- HttpRequest.content_type:表示請求的MIME類型的字符串,從CONTENT_TYPE標頭解析
- HttpRequest.content_params:包含在CONTENT_TYPE標題中的鍵、值參數字典
- HttpRequest.GET:一個類似於字典的對象,包含GET請求中的所有參數,詳情參考QueryDict文檔
- HttpRequest.POST:一個包含所有POST請求的參數,以及包含表單數據的字典,如果需要訪問請求中的原始或非表單數據,可以使用HttpRequest.body屬性;POST中不包含上傳文件的數據。
- HttpRequest.COOKIES:包含所有Cookie信息的字典,鍵和值都為字符串,可以類似字典類型的方式,在cookie中讀寫數據,但是註意cookie是不安全的因此,不要寫敏感重要的信息。
- HttpRequest.FILES:一個類似於字典的對象,包含所有上傳的文件數據,FILES中的每個鍵為<input type=‘file‘ name="" />中的name屬性值,FILES中的每個值是一個UploadedFile;要在Django助攻實現文件上傳,就要靠這個屬性;如果請求方法是POST且請求的<form>中帶有enctype="multipart/form-data"屬性,那麽FILES將包含上傳的文件的數據,否則FILES將為一個空的類似於字典的對象,屬於被忽略,無用的情形。
- HttpRequest.META:包含所有HTTP頭部信息的字典,可用的頭部信息取決於客戶端和服務器,下面是一些示例:
-
- CONTENT_LENGTH —— 請求正文的長度(以字符串計)。
- CONTENT_TYPE —— 請求正文的MIME類型。
- HTTP_ACCEPT —— 可接收的響應Content-Type。
- HTTP_ACCEPT_ENCODING —— 可接收的響應編碼類型。
- HTTP_ACCEPT_LANGUAGE —— 可接收的響應語言種類。
- HTTP_HOST —— 客服端發送的Host頭部。
- HTTP_REFERER —— Referring頁面。
- HTTP_USER_AGENT —— 客戶端的user-agent字符串。
- QUERY_STRING —— 查詢字符串。
- REMOTE_ADDR —— 客戶端的IP地址。想要獲取客戶端的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鍵。
- HttpRequest.resolver_match:代表一個已解析的URL的ResolverMatch實例
- HttpRequest.headers:Django 2.2中的新功能,一個不區分大小寫的類似dict的對象,它提供對請求中所有HTTP加前綴的標題的訪問,每個標題的名稱在User-Agent顯示是用標題-外殼進行樣式化,你可以不區分大小寫的訪問標頭:
{‘Content-Length‘: ‘‘, ‘Content-Type‘: ‘text/plain‘, ‘Host‘: ‘127.0.0.1:8000‘, ‘Connection‘: ‘keep-alive‘, ‘Cache-Control‘: ‘max-age=0‘, ‘Upgrade-Insecure-Requests‘: ‘1‘, ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36‘, ‘Accept‘: ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8‘, ‘Accept-Encoding‘: ‘gzip, deflate, sdch, br‘, ‘Accept-Language‘: ‘zh-CN,zh;q=0.8‘, ‘Cookie‘: ‘sessionid=rff2y86kaa57vpsihwgo5j72v11c4m0i; csrftoken=tPHBVfuGzw4lYSNuaWYEXvJa2oiXlCEZeStm9LSLNfxRKxRY0p6xvYnr0518LN0L‘}
(2)可自定義的屬性
- django不會自動設置下面這些屬性,而是由你自己在應用程序中設置並使用它們:
- HttpRequest.current_app:表示當前APP的名字,URL模版標簽將使用其值作為reverse()方法的current_app參數。
- HttpRequest.urlconf:設置當前請求的根URLconf,用於指定不同的URL路由進入口,這將覆蓋settings中的ROOT_URLCONF設置,將它的值修改為None可以恢復使用ROOT_URLCONF設置
(3)由中間件設置的屬性
django的contrib應用中包含的一些中間件會在請求上設置屬性:
- HttpRequest.session:SessionMiddleware中間件,一個可讀寫的,類似字典的對象,表示當前會話,我們要保存用戶狀態,回話過程等等,靠的就是這個中間件和這個屬性
- HttpRequest.site:CurrentSiteMiddleware中間件:get_current_site()方法返回的site或RequestSite的實例,代表當前站點是哪個;django是支持多站點的,如果你同時上線了多個站點,就需要為每個站點設置一個站點id
- HttpRequest.user:AuthenticationMiddleware中間件,表示當前登錄的用戶的AUTH_USER_MODEL的實例,這個模型是django內置的auth模塊下的User模型,如果用戶當前未登錄,則user將被設置為AnonymousUser的實例,可以使用is_authenticated方法判斷當前用戶是否合法用戶,如下:
if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users.
(4)方法
- HttpRequest.get_host():
根據HTTP_X_FORWARDED_HOST和HTTP_HOST頭部信息獲取請求的原始主機,如果這兩個頭部沒有提供相應的值,則使用SERVER_NAME和SERVER_PORT,如:127.0.0.1:8000
註:當主機位於多個代理的後面,get_host()方法將會失敗,解決辦法之一是使用中間件重寫代理的頭部,如下示例:
from django.utils.deprecation import MiddlewareMixin class MultipleProxyMiddleware(MiddlewareMixin): FORWARDED_FOR_FIELDS = [ ‘HTTP_X_FORWARDED_FOR‘, ‘HTTP_X_FORWARDED_HOST‘, ‘HTTP_X_FORWARDED_SERVER‘, ] def process_request(self, request): """ Rewrites the proxy headers so that only the most recent proxy is used. """ for field in self.FORWARDED_FOR_FIELDS: if field in request.META: if ‘,‘ in request.META[field]: parts = request.META[field].split(‘,‘) request.META[field] = parts[-1].strip()
- HttpRequest.get_port():使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回請求的始發端口
- HttpRequest.get_full_path():返回包含完整參數列表的path。例如:/music/bands/the_beatles/?print=true
- HttpRequest.build_absolute_uri(location):返回location的絕對URI形式;如果location沒有提供,則使用request.get_full_path()的值;
例如:"https://example.com/music/bands/the_beatles/?print=true"
註:不鼓勵在同一站點混合部署HTTP和HTTPS,如果需要將用戶重定向到HTTPS,最好使用Web服務器將所有HTTP流量重定向到HTTPS。
- HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None):從已簽名的Cookie中獲取值,如果簽名不合法則返回django.core.signing.BadSignature
可選參數salt用來為密碼加鹽,提高安全系數。 max_age參數用於檢查Cookie對應的時間戳是否超時。
>>> request.get_signed_cookie(‘name‘) ‘Tony‘ >>> request.get_signed_cookie(‘name‘, salt=‘name-salt‘) ‘Tony‘ # assuming cookie was set using the same salt >>> request.get_signed_cookie(‘nonexistent-cookie‘) ... KeyError: ‘nonexistent-cookie‘ >>> request.get_signed_cookie(‘nonexistent-cookie‘, False) False >>> request.get_signed_cookie(‘cookie-that-was-tampered-with‘) ... BadSignature: ... >>> request.get_signed_cookie(‘name‘, max_age=60) ... SignatureExpired: Signature age 1677.3839159 > 60 seconds >>> request.get_signed_cookie(‘name‘, False, max_age=60) False
HttpRequest.is_secure():如果使用的是Https,則返回True,表示連接是安全的。
HttpRequest.is_ajax():如果請求是通過XMLHttpRequest生成的,則返回True;這個方法的作用就是判斷,當前請求是否通過ajax機制發送過來的。
HttpRequest.read(size=None)
HttpRequest.readline()
HttpRequest.readlines()
HttpRequest.xreadlines()
HttpRequest.iter()
上面的幾個方法都是從HttpRequest實例讀取文件數據的方法。
可以將HttpRequest實例直接傳遞到XML解析器,例如ElementTree:
import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
6、QueryDict對象
在HttpRequest對象中,GET和POST屬性都是一個django.http.QueryDict的實例。也就是說你可以按本文下面提供的方法操作request.POST和request.GET。
request.POST或request.GET的QueryDict都是不可變,只讀的。如果要修改它,需要使用QueryDict.copy()方法,獲取它的一個拷貝,然後在這個拷貝上進行修改操作。
(1)方法
QueryDict 實現了Python字典數據類型的所有標準方法,因為它是字典的子類。
不同之處在於下面:
QueryDict.init(query_string=None, mutable=False, encoding=None):QueryDict實例化方法。註意:QueryDict的鍵值是可以重復的
>>> QueryDict(‘a=1&a=2&c=3‘) <QueryDict: {‘a‘: [‘1‘, ‘2‘], ‘c‘: [‘3‘]}>
如果需要實例化可以修改的對象,添加參數mutable=True
classmethod QueryDict.fromkeys(iterable, value=‘‘, mutable=False, encoding=None):
循環可叠代對象中的每個元素作為鍵值,並賦予同樣的值。
>>> QueryDict.fromkeys([‘a‘, ‘a‘, ‘b‘], value=‘val‘) <QueryDict: {‘a‘: [‘val‘, ‘val‘], ‘b‘: [‘val‘]}>
QueryDict.__getitem__():返回給定鍵的值,如果鍵具有多個值,則返回最後一個值
QueryDict.__setitem__(ke,value):將給定鍵設置為value,只能在可變的QueryDict上調用
QueryDict.__contains__():判斷給定鍵是否存在
QueryDict.get(ke,default=None):同__getitem__()相同,只是多個了默認值返回
QueryDict.setdefault(key,default=None):它在__setitem__()內部使用
QueryDict.update(other_dict):用新的QueryDict或字典更新當前QueryDict,類似dict.update(),但是追加內容,而不是更新並替換它們,如下:
>>> q = QueryDict(‘a=1‘, mutable=True) >>> q.update({‘a‘: ‘2‘}) >>> q.getlist(‘a‘) [‘1‘, ‘2‘] >>> q[‘a‘] # returns the last ‘2‘
QueryDict.items():類似dict.items(),如果有重復項目,返回最近的一個:
>>> q = QueryDict(‘a=1&a=2&a=3‘) >>> list(q.items()) [(‘a‘, ‘3‘)]
QueryDict.values():類似dict.values(),但是只返回最近的值,如下:
>>> q = QueryDict(‘a=1&a=2&a=3‘) >>> list(q.values()) [‘3‘]
QueryDict.copy():使用copy.deepcopy()返回QueryDict對象的副本,此副本是可變的
QueryDict.getlist(key,defautl=None):返回鍵對應的值的列表,如果該鍵不存在並且為提供默認值,則返回一個空列表
QueryDict.setlist(key,list_):為list_設置給定的鍵
QueryDict.appendlist(key,item):將鍵追加到內部與鍵相關聯的列表中
QueryDict.setdefault(key,default=None):類似dict.setdefault(),為某個鍵設置默認值
QueryDict.lists():類似items(),只是它將其中的每個鍵的值作為列表放在一起,如下:
>>> q = QueryDict(‘a=1&a=2&a=3‘) >>> q.lists() [(‘a‘, [‘1‘, ‘2‘, ‘3‘])]
QueryDict.pop(key):返回給定鍵的值的列表,並從QueryDict中移除該值,如鍵不存在則引發異常
>>> q = QueryDict(‘a=1&a=2&a=3‘, mutable=True) >>> q.pop(‘a‘) [‘1‘, ‘2‘, ‘3‘]
QueryDict.popitem():刪除QueryDict任意一個鍵,並返回二值元組,包含鍵和鍵的所有值的列表,在一個空的字典上調用時將引發KeyErro,如下:
>>> q = QueryDict(‘a=1&a=2&a=3‘, mutable=True) >>> q.popitem() (‘a‘, [‘1‘, ‘2‘, ‘3‘])
QueryDict.dict():將QueryDict轉換為python字典數據類型,並返回該字典,如果出現重復的鍵,則將所有的值打包成一個列表,改為新字典中鍵的值
>>> q = QueryDict(‘a=1&a=3&a=5‘) >>> q.dict() {‘a‘: ‘5‘}
QueryDict.urlencode(safe=Noen):為已編碼的格式返回數據字符串:
>>> q = QueryDict(‘a=2&b=3&b=5‘) >>> q.urlencode() ‘a=2&b=3&b=5‘
使用該safe參數傳遞不需要編碼的字符:
>>> q = QueryDict(mutable=True) >>> q[‘next‘] = ‘/a&b/‘ >>> q.urlencode(safe=‘/‘) ‘next=/a%26b/‘
7、HttpResponse對象
HttpResponse類定義在django.http模塊中
HttpRequest對象由django自動創建,而HttpResponse對象則由程序員手動創建,我們編寫的每個視圖都要實例化、填充和返回一個HttpResponse對象,也就是函數的return值。
(1)使用方法
傳遞字符串:
最簡單的方式his傳遞一個字符串作為頁面的內容到HttpResponse構造函數,並返回給用戶:
>>> from django.http import HttpResponse >>> response = HttpResponse("Here‘s the text of the Web page.") >>> response = HttpResponse("Text only, please.", content_type="text/plain") >>> response = HttpResponse(b‘Bytestrings are also accepted.‘)
但,如果要增量添加內容,可以將其response用作類文件對象,使用write()方法不斷往裏增加內容:
>>> response = HttpResponse() >>> response.write("<p>Here‘s the text of the Web page.</p>") >>> response.write("<p>Here‘s another paragraph.</p>")
傳遞可叠代對象:
HttpResponse會立即處理叠代器,並把它的內容存成字符串,最後廢棄這個叠代器,比如文件在讀取後,會立刻調用close()方法,關閉文件
設置頭部字段:
可以把HttpResponse對象當作一個字典一樣,在其中增加和刪除頭部字段:
>>> response = HttpResponse() >>> response[‘Age‘] = 120 >>> del response[‘Age‘]
註意!與字典不同的是,如果要刪除的頭部字段如果不存在,del不會拋出KeyError異常。
HTTP的頭部字段中不能包含換行。所以如果我們提供的頭部字段值包含換行符(CR或者LF),將會拋出BadHeaderError異常
告訴瀏覽器將響應視為文件附件:
讓瀏覽器以文件附件的形式處理響應,需要聲明content_type類型和設置Content-Disposition頭信息,給瀏覽器返回一個微軟電子表格:
>>> response = HttpResponse(my_data, content_type=‘application/vnd.ms-excel‘) >>> response[‘Content-Disposition‘] = ‘attachment; filename="foo.xls"‘
(2)屬性
HttpResponse.content:響應的內容,bytes類型
HttpResponse.charset:編碼的字符集,如果沒指定,將會從content_type中解析出來
HttpResponse.status_code:響應的狀態碼,比如200
HttpResponse.reason_phrase:響應的HTTP原因短語,使用標準原因短語,除非明確設置,否則reason_phrase由status_code的值決定
HttpResponse.streaming:這個屬性的值總是False,由於這個屬性的存在,使得中間件能夠區別對待流式響應和常規響應
HttpResponse.closed:如果響應已關閉,那麽這個屬性的值為True
(3)方法
HttpResponse.init(content=‘‘,content_type=None,status=200,reason=None,charset=None):響應的實例化方法,使用content參數和content_type實例化一個HttpResponse對象;content應該是一個叠代器或者字符串,如果是叠代器,這個叠代器返回的應是字符串,並且這些字符串連接起來形成response的內容,如果不是叠代器或者字符串,那麽在其被接收的時候將轉換成字符串。
content_type是可選的,用於填充HTTP的content_type頭部,如果未指定,默認情況下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET設置成:text/html;charset=utf-8
status是響應的狀態碼,resaon是HTTP響應短語,charset是編碼方式
HttpResponse.has_header(header):檢查頭部中是否有給定的名稱(不區分大小寫),返回true或false
HttpResponse.__setitem__(header,value):設置標頭
HttpResponse.__delitem__(header):刪除標頭
HttpResponse.__getitem__(header):查看標頭
HttpResponse.setdefault(header,value):設置一個頭部,除非該頭部已經設置過了
HttpResponse.set_cookie(key,value=‘‘,max_age=None,expires=None,path=‘/‘,domain=None,secure=None,httponly=False):設置一個cookie,參數與python標準庫中的Morsel.Cookie對象相同;max_age為生存周期以秒為單位;expires為到期時間;domain用於設置跨域的cookie
如果你想阻止客戶端的JavaScript訪問cookie,可以設置httponly=True
HttpResponse.set_signed_cookie(key,value,salt=‘‘,max_age=None,expires=None,path=‘/‘,domain=None,secure=None,httponly=True):與set_cookie類似,但是在設置之前將對cookie進行加密簽名,通常與HttpResponse.get_signed_cookie()一起使用
HttpResponse.delete_cookie(key,path=‘/‘,domain=None):刪除cookie中指定的key,由於cookie工作方式,path和domain應該與set_cookie()使用的值相同,否則cookie不會刪除
HttpResponse.write(content):將HttpResponse實例看作類似文件的對象,往裏添加內容
HttpResponse.flush():清空HttpResponse實例的內容
HttpResponse.tell():將HttpResponse實例看作類似文件的對象,移動位置指針
HttpResponse.getvalue():返回HttpResponse的值,此方法將HttpResponse實例看作是一個類似流的對象
HttpResponse.readable():此方法使HttpResponse實例成為類似流的對象,值始終為False
HttpResponse.seekable():此方法使HttpResponse實例成為類似流的對象,值始終為False
HttpResponse.writable():此方法使HttpResponse實例成為類似流的對象,值始終為True
HttpResponse.writelines(lines):將一個包含行的列表寫入響應對象中,不添加分行符
(4)HttpResponse子類
Django包含許多HttpResponse衍生類(子類),用來處理不同類型的HTTP響應,這些子類存在於django.http之中:
class HttpResponseRedirect:用來重定向,第一個參數必須是重定向到的路徑,可以是完全限定的URL,或沒有域的絕對路徑,或者是相對路徑;它將返回狀態碼302
class HttpResponsePermanentRedirect:永久重定向,返回301狀態碼
class HttpResponseNotModified:未修改頁面,返回304狀態碼
class HttpResponseBadRequest:錯誤的請求,返回400狀態碼
class HttpResponseNotFound:頁面不存在,返回404狀態碼
class HttpResponseForbidden:禁止訪問,返回403狀態碼
class HttpResponseNotAllowed:禁止訪問,返回405狀態碼
class HttpResponseGone:過期,返回410狀態碼
class HttpResponseServerError:服務器錯誤,返回500狀態碼
(5)JsonResponse類
classJsonResponse(data,encoder = DjangoJSONEncoder,safe = True,json_dumps_params = None,**kwargs)
JsonResponse是HttpResponse的一個子類,是Django提供的用於創建JSON編碼類型響應的快捷類
它從父類繼承大部分行為,並具有以下不同點:
它的默認Content-Type頭部設置為application/json
它的第一個參數data,通常應該為一個字典數據類型,如果safe參數設置為False,則可以是任何可JSON序列化的對象
encoder默認為django.core.serializers.json.DjangoJSONEncoder,用於序列化數據
布爾類型參數safe默認為True,如果設置為False,可以傳遞任何對象進行序列化,否則只允許dict實例
典型的用法如下:
>>> from django.http import JsonResponse >>> response = JsonResponse({‘foo‘: ‘bar‘}) >>> response.content b‘{"foo": "bar"}‘
如要序列非dict對象,必須設置safe參數為False,如果不傳遞safe=False,將拋出一個TypeError
>>> response = JsonResponse([1, 2, 3], safe=False)
如果你需要使用不同的JSON編碼器類,可以傳遞encoder參數給構造函數:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
(6)StreamingHttpResponse類
StreamingHttpResponse類被用來從Django響應一個流式對象到瀏覽器。如果生成的響應太長或者是占用的內存較大,這麽做可能更有效率。 例如,它對於生成大型的CSV文件非常有用。
StreamingHttpResponse不是HttpResponse的衍生類(子類),因為它實現了完全不同的應用程序接口。但是,除了幾個明顯不同的地方,兩者幾乎完全相同:
它將被賦予一個叠代器,產生字符串作為內容
除非通過叠代響應對象本身,否則無法訪問其內容,只有在將響應返回給客戶端時才會發生這種情況
它沒有content屬性,相反,它有一個streaming_content屬性
你不能使用類文件對象tell()或write()方法
(7)FileResponse類
class FileResponse(open_file,as_attachment = False,filename=‘‘,**kwargs)
文件類型響應,通常用於給瀏覽器返回一個文件附件,FileResponse是StreamingHttpResponse的衍生類,為二進制文件專門做了優化
如果as_attachment=True,則要求瀏覽器將文件作為下載提供給用戶
如果open_file沒有名稱或名稱open_file不合適,請使用filename參數提供自定義文件名
FileResponse接受任何具有二進制內容的類文件對象,如下以二進制模式打開文件:
>>> from django.http import FileResponse >>> response = FileResponse(open(‘myfile.png‘, ‘rb‘))
上面的文件將自動關閉,因此不要使用上下文管理器打開它
FileResponse.set_headers方法,在2.1中添加的新功能,它在初始化期間自動調用和設置不同的報頭(Content-Length,Content-Type和Content-Disposition),使用哪種報頭取決於打開的文件。
-------------------------------------------------------------------------------------------------------------------
django views視圖