1. 程式人生 > >django views視圖

django views視圖

信息部 ngs scrip eno 結果 returns 阻止 添加內容 elf

視圖函數簡稱視圖,本質上是一個簡單的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, HttpResponseNotFound

def 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(bBytestrings 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視圖