Django 系列博客(七)

来源:https://www.cnblogs.com/zuanzuan/archive/2019/01/10/10247664.html
-Advertisement-
Play Games

Django 系列博客(七) 前言 本篇博客介紹 Django 中的視圖層中的相關參數,HttpRequest 對象、HttpResponse 對象、JsonResponse,以及視圖層的兩種響應方式 CBV 和 FBV,還有簡單的文件上傳。 視圖函數 一個視圖函數,簡稱視圖,是一個簡單的Pytho ...


Django 系列博客(七)

前言

本篇博客介紹 Django 中的視圖層中的相關參數,HttpRequest 對象、HttpResponse 對象、JsonResponse,以及視圖層的兩種響應方式 CBV 和 FBV,還有簡單的文件上傳。

視圖函數

一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求並且返回Web響應。響應可以是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西都可以。無論視圖本身包含什麼邏輯,都要返迴響應。代碼寫在哪裡也無所謂,只要它在你的Python目錄下麵。除此之外沒有更多的要求了——可以說“沒有什麼神奇的地方”。為了將代碼放在某處,約定是將視圖放置在項目或應用程式目錄中的名為views.py的文件中。

下麵是一個返回當前日期和時間作為 HTML 文檔的視圖:

from django.shortcuts import render, HttpResponse, HttpResponseRedirect, redirect
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

這段代碼解析:

  • django.shortcuts模塊導入了HttpResponse類,以及Python的datetime庫;
  • 定義了current_datetime函數。它就是視圖函數。每個視圖函數都使用HttpRequest對象作為第一個參數,並且通常稱之為request

註意,視圖函數的名稱並不重要;不需要用一個統一的命名方式來命名,以便讓Django識別它。我們將其命名為current_datetime,是因為這個名稱能夠精確地反映出它的功能。

  • 會返回一個HttpResponse對象,其中包含生成的響應。每個視圖函數都負責返回一個HttpResponse對象。

在視圖層最重要的就是要熟悉兩個對象:請求對象(request)和響應對象(HttpResponse)。

HttpRequest 對象

request 屬性

Django 將請求報文中的請求行、請求頭、請求體封裝成 HttpRequest 類中的屬性。除了特殊說明之外,其他的均為只讀屬性。

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"
  註意和path的區別:http://127.0.0.1:8001/order/?name=lqz&age=10

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 對象

響應對象主要有三種形式:前面的博客有相關介紹

  1. HttpResponse();
  2. render();
  3. redirect().

HttpResponse()括弧內直接跟一個具體的字元串作為響應體,比較直接和簡單,所以這裡介紹後兩種

render()

render(request, template_name[, context])

結合給定的模板和一個上下文字典,返回一個經過 Django渲染後的HttpResponse 對象到前端。

參數:

  1. request:用於生成響應的請求對象;
  2. template_name:要使用的模板的完整名稱,可選的參數;
  3. context:添加到模板上下文的一個字典。預設是一個空字典,如果字典中的某個值是可調用的,視圖將在渲染模板之前調用它;

render 方法就是將一個模板頁面中的模板語法進行渲染,最終渲染成一個 HTML 頁面作為響應返回給前端。

redirect()

傳遞要重定向的一個硬編碼的URL

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

也可以是一個完成的 url

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

JsonResponse對象

向前端返回一個 json 格式的字元串,有兩種方式:

第一種方式

import json
data = {'name': 'musibii', 'age': 18}
return HttpResponse(json.dumps(data))
# 從這裡可以看出其實 Jsonresponse內部也是調用了 json 的 dumps 方法進行轉換

第二種方式

from django.http import JsonResponse
data = {'name': 'musibii', 'age': 18}

return JsonResponse(data1,safe=False)
# safe參數是一種安全機制,因為如果要傳輸列表類型的數據時,會因為內部的相關機制會產生錯誤。

CBV 和 FBV

CBV 基於類的視圖(Class Base View)和 FBV 基於函數的視圖(Function Base View)

CBV

from django.views import View

class Login(View):
    
    def dispatch(self, request, *args, **kwargs):
        print(request)
        print(args)
        print(kwargs)
        # 可以寫類似裝飾器的東西,在前後加代碼
        obj=super().dispatch(request, *args, **kwargs)
        return obj

    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        name = request.POST.get('name')
        ret = BookInfo.objects.filter(name=name).first()
        print(type(ret))
        dic = {}
        print(ret.name)
        print(type(ret.__dict__))
        for key, value in (ret.__dict__).items():
            if key[0].startswith('_'):
                continue
            print(key)
            dic[key] = value
            # print(dic)
       
       # 第二種
       # ret = BookInfo.objects.all() 
       # lis = []
       # for info in ret:
       #     dic = {}
       #     for k, v in (info.__dict__).items():
       #         if key[0].startswitch(''):
       #             continue
       #         dic[key] = v
       #     lis.append(dic)

       # 第三種
       # li = []
       # ret = BookInfo.objects.all()
       # for book in ret:
       #     dic = {}
       #     for field in book._meta.fields:
       #         dic[field.name] = getattr(book, field.name)
       #     li.append(dic)
       return JsonResponse(dic, json_dumps_params={'ensure_ascii': False})

FBV

def file_upload(request):
    if request.method=="GET":
        return render(request,'file_upload.html')
    else:
        print(request.POST)
        print(request.FILES)
        # print(request.body)
        # FILES是一個字典,
        # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}>
        # 拿到上傳的文件對象

        file=request.FILES.get('myfile')
        print(type(file))
        from django.core.files.uploadedfile import InMemoryUploadedFile
        with open(file.name,'wb') as f:
            # for line in file.chunks():
            for line in file:
                f.write(line)
        return HttpResponse('上傳成功')

簡單文件上傳

模板文件

# upload_file.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="" method="post" enctype="multipart/form-data">
    <p>用戶名:<input type="text" name="name"></p>
    <input type="file" name="myfile">
{#    <input type="file" name="myfile2">#}
    <input type="submit" value="提交">

</form>

</body>
</html>

路由文件

from django.conf.urls import url
from app01 import views
urlpatterns = [
    url(r'^upload_file/$', views.UploadFile.as_view()),
]

視圖文件

class UploadFile(View):

    def get(self, request):
        return render(request, 'upload_file.html')

    def post(self, request):
        file = request.FILES.get('myfile')
        # print(file['file'])
        from django.core.files.uploadedfile import InMemoryUploadedFile
        print(time.time())
        filename = str(time.time()).split('.')[0] + file.name
        with open(filename, 'wb') as f:
            for line in file:
                f.write(line)
        return HttpResponse('上傳成功')

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是工廠模式? 提到工廠,我們肯定首先想到的就是生產東西的地方,之所以叫做工廠模式也正是如此,工廠模式就是根據工廠類來調用自身靜態方法來生產不同對象實例。 工廠模式的應用場景還是挺多的,比如我們使用的各個框架(ThinkPHP,Laravel),為什麼我們定了各個控制器和方法後通過在瀏覽器通過輸入 ...
  • 單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個實例。即一個類只有一個對象實例。 提示: 資料庫連接池的設計一般也是採用單例模式,因為資料庫連接是一種資料庫資源。資料庫軟體系統中使用資料庫連接池,主要是節省打開或者關閉資料庫連 ...
  • 按理說應該把書全都看完一遍,再開始寫博客比較科學,會有比較全面的認識。 但是既然都決定要按規律更新博客了,只能看完一個設計模式寫一篇了。 也算是逼自己思考了,不是看完就過,至少得把代碼自己都敲一遍。 剛開始可能寫的比較淺顯,更像是讀書筆記,只能未來回來完善了。 廢話啰嗦到這,開始正題。 文章是以一個 ...
  • 一、UML概述 UML(UnifiedModelingLanguage)統一建模語言,是面向對象軟體的標準化建模語言。由於面向對象軟體開發需要經過OOA(面向對象分析),OOD(面向對象設計),OOP(面向對象編程)三個階段,每個階段都需要統一的符號設計描述和交流,而UML就是這種統一的符號表示。 ...
  • import和liabrary指令可以幫助你創建模塊化,可復用的代碼。庫不僅僅提供API,也是一個私有化單元:庫中已下劃線(_)開頭的類都是對外不可訪問的。每個Dart的應用也是一個包,儘管它沒有使用包的聲明。 庫都採用包的形式發佈。具體看 "Pub Package and Asset Manage ...
  • 一、打碼的作用 在進行爬蟲過程中,部分網站的登錄驗證碼是比較簡單的,例如四個英文數字隨機組合而成的驗證碼,有的是全數字隨機組成的驗證碼,有的是全中文隨機組成的驗證碼。為了爬蟲進行自動化,需要解決自動登錄的問題,而驗證碼問題成了第一道坎。起初想到用百度AI的圖像識別技術進行識別,但識別結果卻很差,最後 ...
  • 1. CSDN學院課程數據 寫在前面 今天又要抓取一個網站了,選擇恐懼症使得我不知道該拿誰下手,找來找去,算了,還是抓取CSDN學院吧,CSDN學院的網站為 "https://edu.csdn.net/courses" 我看了一下這個網址,課程數量也不是很多,大概有 門課程,數據量不大,用單線程其實 ...
  • 1.生成9位字母的密碼 使用random.choice函數,此函數需要一個序列,因此給定一個序列包含a-z,A-Z 2:生成9位數字和字母的密碼,密碼可能隨機出現數字和字母此題在上一題的基礎上先生成一個序列包含所有字母和數字,然後使用random.choice()函數 3.檢測密碼強度 c1 : 長 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...