溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Django視圖(View)

發(fā)布時間:2020-07-28 04:06:16 來源:網(wǎng)絡(luò) 閱讀:437 作者:小飛額 欄目:編程語言

Django 視圖

聲明:文章部分內(nèi)容來源https://www.cnblogs.com/maple-shaw/articles/9285269.html

  • 視圖的概念:一個視圖函數(shù)(類),簡稱視圖,是一個簡單的Python 函數(shù)(類),它接受Web請求并且返回Web響應(yīng)。響應(yīng)可以是一張網(wǎng)頁的HTML內(nèi)容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片
  • 視圖的規(guī)范:無論視圖本身包含什么邏輯,都要返回響應(yīng)。代碼寫在哪里也無所謂,只要它在你當(dāng)前項(xiàng)目目錄下面。除此之外沒有更多的要求了——可以說“沒有什么神奇的地方”。為了將代碼放在某處,大家約定成俗將視圖放置在項(xiàng)目(project)或應(yīng)用程序(app)目錄中的名為views.py的文件中。
簡單的視圖
from django.http import HttpResponse
import datetime
#從 django.http模塊導(dǎo)入了HttpResponse類,以及Python的datetime模塊。

def current_datetime(request):
    #定義了current_datetime函數(shù)。它就是視圖函數(shù)。每個視圖函數(shù)都使用HttpRequest對象作為第一個參數(shù),并且通常稱之為request。
    now = datetime.datetime.now()
    #獲取當(dāng)前時間
    html = "<html><body>It is now %s.</body></html>" % now
    #定義一個變量等于后面的字符串
    return HttpResponse(html)
#返回一個HttpResponse對象,其中包含生成的響應(yīng)。每個視圖函數(shù)都負(fù)責(zé)返回一個HttpResponse對象。

Django使用請求和響應(yīng)對象來通過系統(tǒng)傳遞狀態(tài)。

當(dāng)瀏覽器向服務(wù)端請求一個頁面時,Django創(chuàng)建一個HttpRequest對象,該對象包含關(guān)于請求的元數(shù)據(jù)。然后,Django加載相應(yīng)的視圖,將這個HttpRequest對象作為第一個參數(shù)傳遞給視圖函數(shù)。

每個視圖負(fù)責(zé)返回一個HttpResponse對象。
CBV和FBV
FBV:基于函數(shù)的視圖
  • fbv基礎(chǔ)格式
from django.http import HttpResponse
#導(dǎo)入HttpResponse模塊,這個模塊可以幫我們把字符串返回給網(wǎng)頁
def add_class(request):
    if request.method == "POST":
        return HttpResponse("POST")
    return HttpResponse('GET')
#實(shí)現(xiàn)效果,如果發(fā)過來的是GET請求就返回GET,如果是POST請求就返回POST
CBV:基于類的視圖
  • cbv的基礎(chǔ)格式
from django.http import HttpResponse
from django.views import View
#導(dǎo)入HttpResponse和View導(dǎo)入視圖模塊,方便我們創(chuàng)建類時繼承View
class AddClass(View):

    def get(self, request):#處理get請求
        return HttpResponse('get')

    def post(self, request):#處理post請求
        return HttpResponse('post')
#實(shí)現(xiàn)效果,如果發(fā)過來的是GET請求就返回GET,如果是POST請求就返回POST    
  • 使用cbv的優(yōu)點(diǎn)可以根據(jù)接收的不同請求,執(zhí)行相應(yīng)的方法,在fbv中需要更多if判斷,不如cbv,看起來方便
  • 使用cbv時,url的配置
#在url中的修改配置
url(r'^add_class/$', views.要使用的類的名字.as_view())
給視圖加裝飾器
給FBV加裝飾器
  • FBV本身就是一個函數(shù),所以根普通的函數(shù)加裝飾器方法無差別:

    def wrapper(func):
      def inner(*args, **kwargs):
          start_time = time.time()#在執(zhí)行前計(jì)算時間戳
          ret = func(*args, **kwargs)
          end_time = time.time()#執(zhí)行后的時間戳
          print("函數(shù)執(zhí)行時間是:", end_time-start_time)
          return ret
      return inner
    #裝飾器作用,求出函數(shù)執(zhí)行的時間,并輸出
    
    @wrapper
    def add_class(request):
      if request.method == "POST":
          return HttpResponse("POST")
      return HttpResponse('GET')    
給CBV加裝飾器
  • Django中提供了method_decorator裝飾器用于將函數(shù)裝飾器轉(zhuǎn)換為方法裝飾器。

    from django.utils.decorators import method_decorator#導(dǎo)入方法
    def timer(func):
      def inner(*args, **kwargs):
          start_time = time.time()#在執(zhí)行前計(jì)算時間戳
          ret = func(*args, **kwargs)
          end_time = time.time()#執(zhí)行后的時間戳
          print("函數(shù)執(zhí)行時間是:", end_time-start_time)
          return ret
      return inner
    
    #直接加在類中方法上
    @method_decorator(timer)括號內(nèi)為裝飾器自己寫的裝飾器名字
    def get(self, request, *args, **kwargs):
    
    #加在dispatch方法上
    #方式一
    @method_decorator(timer)
    def dispatch(self, request, *args, **kwargs):
      # print('before')
      ret = super().dispatch(request, *args, **kwargs)
      # print('after')
      return ret
    #方式二
    @method_decorator(timer,name='dispatch')
    class AddPublisher(View):
    
    #加在類上
    #@method_decorator(timer,name='post')name代表要加在類中方法的名字
    @method_decorator(timer,name='get')
    class AddPublisher(View):
  • 當(dāng)然直接給類中方法加裝飾器也是可以的,不過和通過使用method_decorator的有一些區(qū)別,下面我們就通過代碼看下具體區(qū)別吧

    直接裝飾,打印func,args結(jié)果:
    func結(jié)果:<function AddClass.get at 0x03DF5390> 
    args結(jié)果:(<app.views.AddClass object at 0x040D8D10>, <WSGIRequest: GET '/cbv'>)
    
    通過method_decorator裝飾,打印func,args結(jié)果:
    func結(jié)果:<function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x045ED540> 
    args結(jié)果:(<WSGIRequest: GET '/cbv'>,)
    
    區(qū)別:通過上面代碼,我們可以看出直接加裝飾器的話,裝飾器的args是有兩個值的,后面的值才是request對象,使用時需要取索引位置1的值才能夠調(diào)用request對象,
    而通過method_decorator裝飾,裝飾器args只有一個值,使用request時只需要取索引位置0的值就能夠調(diào)用request對象,所以我們使用時需要注意加裝飾器的方法和args到底應(yīng)該取得哪個位置?。。。?!
request對象
request屬性 作用
request.methot 請求方式
request.path_info URL的路徑 不包含ip和端口 不包含參數(shù)
request.POST POST請求提交的數(shù)據(jù)
request.body 請求體, byte類型 request.POST的數(shù)據(jù)就是從body里面提取到的
request.FILES 上傳的文件
request.META 請求頭
request.COOKIES 后面講
request.session 后面講
request.encoding 表示提交的數(shù)據(jù)的編碼方式(如果為 None 則表示使用 DEFAULT_CHARSET 的設(shè)置,默認(rèn)為 'utf-8')。
  • request.body

      一個字符串,代表請求報文的主體。在處理非 HTTP 形式的報文時非常有用,例如:二進(jìn)制圖片、XML,Json等。
    
      但是,如果要處理表單數(shù)據(jù)的時候,推薦還是使用 HttpRequest.POST 。
    
      另外,我們還可以用 python 的類文件方法去操作它,詳情參考 HttpRequest.read() 。
  • request.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 將為一個空的類似于字典的對象。
    • 上傳文件實(shí)例
    def file(request):#定義一個函數(shù)
        if request.method == "POST":#如果類型為post
            fname = request.FILES.get('f1')#取出發(fā)送來的對象
            with open(fname.name,'wb') as f:#fname.name方法能夠取出上傳的文件名稱
                for i in fname.chunks():#fname.chunks()方法能夠取出上傳的數(shù)據(jù),進(jìn)行for循環(huán)
                    f.write(i)#把循環(huán)的值寫入打開的文件
                return HttpResponse('上傳ok')#上傳完畢后返回成功
        return render(request,'sc.html')#如果不是post請求返回sc.html頁面
  • request.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 鍵。
    
    #注意:鍵值對的值是多個的時候,比如checkbox類型的input標(biāo)簽,select標(biāo)簽,需要用:
    request.POST.getlist("")取值
request方法 作用
request.get_full_path() URL的路徑 不包含ip和端口 包含參數(shù)
request.is_ajax() 判斷是不是ajax請求
Httpresponse對象
  • 與由Django自動創(chuàng)建的HttpRequest對象相比,HttpResponse對象是我們的職責(zé)范圍了。我們寫的每個視圖都需要實(shí)例化,填充和返回一個HttpResponse。
  • HttpResponse類位于django.http模塊中。
Httpresponse屬性 作用
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)。

    • 實(shí)例
    from django.shortcuts import render, redirect, HttpResponse
    HttpResponse('字符串')    ——》  ’字符創(chuàng)‘
    render(request,'模板的文件名',{k1:v1})   ——》 返回一個完整的TML頁面
    redirect('重定向的地址')    ——》 重定向   Location : 地址
    
    from django.http.response import JsonResponse
    JsonResponse({})
    JsonResponse([],safe=False)
    • JsonResponse默認(rèn)只能傳遞字典類型,如果非要傳非字典類型需要設(shè)置safe關(guān)鍵字參數(shù)
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI