Django如何實現(xiàn)視圖

這篇文章主要介紹了Django如何實現(xiàn)視圖,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)新樂,10多年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792

Django的View(視圖)

一個視圖函數(shù)(類),簡稱視圖,是一個簡單的Python 函數(shù)(類),它接受Web請求并且返回Web響應(yīng)。

響應(yīng)可以是一張網(wǎng)頁的HTML內(nèi)容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。

一個簡單的視圖

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模塊導(dǎo)入了HttpResponse類,以及Python的datetime庫。

  • 接著,我們定義了current_datetime函數(shù)。它就是視圖函數(shù)。每個視圖函數(shù)都使用HttpRequest對象作為第一個參數(shù),并且通常稱之為request。

  • 注意,視圖函數(shù)的名稱并不重要;不需要用一個統(tǒng)一的命名方式來命名,以便讓Django識別它。我們將其命名為current_datetime,是因為這個名稱能夠比較準(zhǔn)確地反映出它實現(xiàn)的功能。

  • 這個視圖會返回一個HttpResponse對象,其中包含生成的響應(yīng)。每個視圖函數(shù)都負(fù)責(zé)返回一個HttpResponse對象。

FBV(基于函數(shù)的視圖)和CBV(基于類的視圖)

基于函數(shù)的view,就叫FBV。還可以把view寫成基于類的,叫CBV。

FBV版

# FBV版添加班級
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")

CBV版

# CBV版添加班級
from django.views import View

class AddClass(View):

    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

注意:使用CBV時,urls.py中也做對應(yīng)的修改:

# urls.py中
url('add_class/', views.AddClass.as_view()),

給視圖加裝飾器

使用裝飾器裝飾FBV

FBV本身就是一個函數(shù),所以和給普通的函數(shù)加裝飾器無差:

def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time-start_time)
        return ret
    return inner


# FBV版添加班級
@wrapper
def add_class(request):
    if request.method == "POST":
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")
    return render(request, "add_class.html")

使用裝飾器裝飾CBV

類中的方法與獨(dú)立函數(shù)不完全相同,因此不能直接將函數(shù)裝飾器應(yīng)用于類中的方法 ,我們需要先將其轉(zhuǎn)換為方法裝飾器。

Django中提供了method_decorator裝飾器用于將函數(shù)裝飾器轉(zhuǎn)換為方法裝飾器。

# CBV版添加班級
from django.views import View
from django.utils.decorators import method_decorator

class AddClass(View):

    @method_decorator(wrapper)
    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

Request對象和Response對象

request對象

當(dāng)一個頁面被請求時,Django就會創(chuàng)建一個包含本次請求原信息的HttpRequest對象。Django會將這個對象自動傳遞給響應(yīng)的視圖函數(shù),一般視圖函數(shù)約定俗成地使用 request參數(shù)承接這個對象。官方文檔

請求相關(guān)的常用值

  • path_info返回用戶訪問url,不包括域名

  • method請求中使用的HTTP方法的字符串表示,全大寫表示。

  • GET包含所有HTTP GET參數(shù)的類字典對象

  • POST包含所有HTTP POST參數(shù)的類字典對象

  • body請求體,byte類型 request.POST的數(shù)據(jù)就是從body里面提取到的

屬性

所有的屬性應(yīng)該被認(rèn)為是只讀的,除非另有說明。

屬性:
  django將請求報文中的請求行、頭部信息、內(nèi)容主體封裝成 HttpRequest 類中的屬性。
   除了特殊說明的之外,其他均為只讀的。


0.HttpRequest.scheme
   表示請求方案的字符串(通常為http或https)

1.HttpRequest.body

  一個字符串,代表請求報文的主體。在處理非 HTTP 形式的報文時非常有用,例如:二進(jìn)制圖片、XML,Json等。

  但是,如果要處理表單數(shù)據(jù)的時候,推薦還是使用 HttpRequest.POST 。

  另外,我們還可以用 python 的類文件方法去操作它,詳情參考 HttpRequest.read() 。

 

2.HttpRequest.path

  一個字符串,表示請求的路徑組件(不含域名)。

  例如:"/music/bands/the_beatles/"



3.HttpRequest.method

  一個字符串,表示請求使用的HTTP 方法。必須使用大寫。

  例如:"GET"、"POST"

 

4.HttpRequest.encoding

  一個字符串,表示提交的數(shù)據(jù)的編碼方式(如果為 None 則表示使用 DEFAULT_CHARSET 的設(shè)置,默認(rèn)為 'utf-8')。
   這個屬性是可寫的,你可以修改它來修改訪問表單數(shù)據(jù)使用的編碼。
   接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數(shù)據(jù))將使用新的 encoding 值。
   如果你知道表單數(shù)據(jù)的編碼不是 DEFAULT_CHARSET ,則使用它。

 

5.HttpRequest.GET 

  一個類似于字典的對象,包含 HTTP GET 的所有參數(shù)。詳情請參考 QueryDict 對象。

 

6.HttpRequest.POST

  一個類似于字典的對象,如果請求中包含表單數(shù)據(jù),則將這些數(shù)據(jù)封裝成 QueryDict 對象。

  POST 請求可以帶有空的 POST 字典 —— 如果通過 HTTP POST 方法發(fā)送一個表單,但是表單中沒有任何的數(shù)據(jù),QueryDict 對象依然會被創(chuàng)建。
   因此,不應(yīng)該使用 if request.POST  來檢查使用的是否是POST 方法;應(yīng)該使用 if request.method == "POST" 

  另外:如果使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。

 7.HttpRequest.COOKIES

  一個標(biāo)準(zhǔn)的Python 字典,包含所有的cookie。鍵和值都為字符串。

 

8.HttpRequest.FILES

  一個類似于字典的對象,包含所有的上傳文件信息。
   FILES 中的每個鍵為<input type="file" name="" /> 中的name,值則為對應(yīng)的數(shù)據(jù)。

  注意,F(xiàn)ILES 只有在請求的方法為POST 且提交的<form> 帶有enctype="multipart/form-data" 的情況下才會
   包含數(shù)據(jù)。否則,F(xiàn)ILES 將為一個空的類似于字典的對象。

 

9.HttpRequest.META

   一個標(biāo)準(zhǔn)的Python 字典,包含所有的HTTP 首部。具體的頭部信息取決于客戶端和服務(wù)器,下面是一些示例:

    CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。
    CONTENT_TYPE —— 請求的正文的MIME 類型。
    HTTP_ACCEPT —— 響應(yīng)可接收的Content-Type。
    HTTP_ACCEPT_ENCODING —— 響應(yīng)可接收的編碼。
    HTTP_ACCEPT_LANGUAGE —— 響應(yīng)可接收的語言。
    HTTP_HOST —— 客服端發(fā)送的HTTP Host 頭部。
    HTTP_REFERER —— Referring 頁面。
    HTTP_USER_AGENT —— 客戶端的user-agent 字符串。
    QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。
    REMOTE_ADDR —— 客戶端的IP 地址。
    REMOTE_HOST —— 客戶端的主機(jī)名。
    REMOTE_USER —— 服務(wù)器認(rèn)證后的用戶。
    REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。
    SERVER_NAME —— 服務(wù)器的主機(jī)名。
    SERVER_PORT —— 服務(wù)器的端口(是一個字符串)。
   從上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,請求中的任何 HTTP 首部轉(zhuǎn)換為 META 的鍵時,
    都會將所有字母大寫并將連接符替換為下劃線最后加上 HTTP_  前綴。
    所以,一個叫做 X-Bender 的頭部將轉(zhuǎn)換成 META 中的 HTTP_X_BENDER 鍵。

 
10.HttpRequest.user

  一個 AUTH_USER_MODEL 類型的對象,表示當(dāng)前登錄的用戶。

  如果用戶當(dāng)前沒有登錄,user 將設(shè)置為 django.contrib.auth.models.AnonymousUser 的一個實例。你可以通過 is_authenticated() 區(qū)分它們。

    例如:

    if request.user.is_authenticated():
        # Do something for logged-in users.
    else:
        # Do something for anonymous users.
     

       user 只有當(dāng)Django 啟用 AuthenticationMiddleware 中間件時才可用。

     -------------------------------------------------------------------------------------

    匿名用戶
    class models.AnonymousUser

    django.contrib.auth.models.AnonymousUser 類實現(xiàn)了django.contrib.auth.models.User 接口,但具有下面幾個不同點(diǎn):

    id 永遠(yuǎn)為None。
    username 永遠(yuǎn)為空字符串。
    get_username() 永遠(yuǎn)返回空字符串。
    is_staff 和 is_superuser 永遠(yuǎn)為False。
    is_active 永遠(yuǎn)為 False。
    groups 和 user_permissions 永遠(yuǎn)為空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引發(fā) NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。

 

11.HttpRequest.session

   一個既可讀又可寫的類似于字典的對象,表示當(dāng)前的會話。只有當(dāng)Django 啟用會話的支持時才可用。
    完整的細(xì)節(jié)參見會話的文檔。

上傳文件示例

def upload(request):
    """
    保存上傳文件前,數(shù)據(jù)需要存放在某個位置。默認(rèn)當(dāng)上傳文件小于2.5M時,django會將上傳文件的全部內(nèi)容讀進(jìn)內(nèi)存。從內(nèi)存讀取一次,寫磁盤一次。
    但當(dāng)上傳文件很大時,django會把上傳文件寫到臨時文件中,然后存放到系統(tǒng)臨時文件夾中。
    :param request: 
    :return: 
    """
    if request.method == "POST":
        # 從請求的FILES中獲取上傳文件的文件名,file為頁面上type=files類型input的name屬性值
        filename = request.FILES["file"].name
        # 在項目目錄下新建一個文件
        with open(filename, "wb") as f:
            # 從上傳的文件對象中一點(diǎn)一點(diǎn)讀
            for chunk in request.FILES["file"].chunks():
                # 寫入本地文件
                f.write(chunk)
        return HttpResponse("上傳OK")

方法

鍵值對的值是多個的時候,比如checkbox類型的input標(biāo)簽,select標(biāo)簽,需要用:

request.POST.getlist("hobby")

Response對象

使用

傳遞字符串

from django.http import HttpResponse
response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")

設(shè)置或刪除響應(yīng)頭信息

response = HttpResponse()
response['Content-Type'] = 'text/html; charset=UTF-8'
del response['Content-Type']

屬性

  • HttpResponse.content:響應(yīng)內(nèi)容

  • HttpResponse.charset:響應(yīng)內(nèi)容的編碼

  • HttpResponse.status_code:響應(yīng)的狀態(tài)碼

JsonResponse對象

JsonResponse是HttpResponse的子類,專門用來生成JSON編碼的響應(yīng)。

from django.http import JsonResponse

response = JsonResponse({'foo': 'bar'})
print(response.content)

b'{"foo": "bar"}'

默認(rèn)只能傳遞字典類型,如果要傳遞非字典類型需要設(shè)置一下safe關(guān)鍵字參數(shù)。

response = JsonResponse([1, 2, 3], safe=False)

Django shortcut functions

官方文檔

render()

Django如何實現(xiàn)視圖

參數(shù):

- request: 用于生成響應(yīng)的請求對象。
- template_name:要使用的模板的完整名稱,可選的參數(shù)
- context:添加到模板上下文的一個字典。默認(rèn)是一個空字典。如果字典中的某個值是可調(diào)用的,視圖將在渲染模板之前調(diào)用它。
- content_type:生成的文檔要使用的MIME類型。默認(rèn)為 DEFAULT_CONTENT_TYPE 設(shè)置的值。默認(rèn)為'text/html'
- status:響應(yīng)的狀態(tài)碼。默認(rèn)為200。
- useing: 用于加載模板的模板引擎的名稱。

一個簡單的例子:

from django.shortcuts import render

def my_view(request):
    # 視圖的代碼寫在這里
    return render(request, 'myapp/index.html', {'foo': 'bar'})

redirect()

傳遞一個視圖的名稱

def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

傳遞要重定向到的一個具體的網(wǎng)址

def my_view(request):
    ...
    return redirect('/some/url/')

可以是一個完整的網(wǎng)址

def my_view(request):
    ...
    return redirect('http://example.com/')

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Django如何實現(xiàn)視圖”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

分享文章:Django如何實現(xiàn)視圖
網(wǎng)頁路徑:http://muchs.cn/article14/ipgige.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄做網(wǎng)站、網(wǎng)站策劃響應(yīng)式網(wǎng)站、品牌網(wǎng)站設(shè)計網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司