Django之視圖

来源:https://www.cnblogs.com/yifchan/archive/2019/08/26/python-1-27.html
-Advertisement-
Play Games

Django之視圖,內容包括 視圖,HttpReqeust對象,ajax請求。其中,視圖 包括 視圖函數的使用,url匹配的過程,錯誤視圖處理,捕捉url參數,普通登錄案例;HttpReqeust對象 包括 屬性,QueryDict對象;ajax請求 包括 python和ajax結合使用,ajax同... ...


Django1.8.2中文文檔:Django1.8.2中文文檔

視圖

視圖的功能

接收請求,進行處理,與M和T進行交互,返回應答。
返回html內容 HttpResponse,也可能重定向 redirect,還可以返回json數據。

 

視圖函數的使用

使用

1)定義視圖函數
request參數必須有。是一個HttpRequest類型的對象。參數名可以變化,但最好不要更改。
2)配置url
建立url和視圖函數之間的對應關係。

 

url配置的過程

  • 1)在項目的urls文件中包含具體應用的urls文件,在具體應用的urls文件中包含具體url和視圖的對應關係。
  • 2)url配置項是定義在一個名叫urlpatterns的列表中,其中的每一個元素就是一個配置項,每一個配置項都調用url函數。

如下

test1000/url.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('booktest.urls')),  # 包含booktest應用中的路由文件
]

booktest/url.py

urlpatterns = [
    url(r'^index/', views.index),  # 顯示圖書信息
    url(r'^create/', views.create),  # 添加一本書籍
    url(r'^delete(\d+)/', views.delete),  # 刪除一本書籍
]

 

url匹配的過程

url匹配圖解

匹配示例:

url:http://127.0.0.1:8000/aindex?a=1

  • 1) 去除功能變數名稱和後面的參數,剩下/aindex,再把前面的/去掉,剩下aindex
  • 2) 拿aindex先到項目的url.py文件中進行從上到下的匹配,匹配成功之後執行後面對應的處理動作,就是把匹配成功的部分a字元去除,然後拿剩下的部分index到應用的urls.py文件中再進行從上到下的匹配。
  • 3) 如果匹配成功則調用相應的視圖產生內容返回給客戶端。如果匹配失敗則產生404錯誤。

 

錯誤視圖

當我們在開發時,可以設置settings文件裡面的DEBUG=True,但當我們要上線產品時,應該設置為False,否則會把網站的信息暴露出來。
開發時:

DEBUG = True
ALLOWED_HOSTS = []

要上線時:

DEBUG = True
ALLOWED_HOSTS = ['*']

 

404: 找不到頁面。可能原因

  • a)url沒有配置
  • b)url配置錯誤
  • c)瀏覽器url’/’問題

500: 伺服器端的錯誤。可能原因

  • a)視圖出錯

 

自定義404頁面

修改為上線模式後,在templates下新建並編寫一個404.html,即可。
在使用這個頁面的過程中,Django會傳過來一個模板變數,{{ request_path }},表示用戶請求路徑。

500錯誤頁面同理。

 

捕捉url參數

進行url匹配時,把所需要的捕獲的部分設置成一個正則表達式組,這樣django框架就會自動把匹配成功後相應組的內容作為參數傳遞給視圖函數。
1)位置參數
位置參數,參數名可以隨意指定


2)關鍵字參數:在位置參數的基礎上給正則表達式組命名即可。
?P<組名>
關鍵字參數,視圖中參數名必須和正則表達式組名一致.

 

捕獲url參數示例:

url(r'^delete(\d+)/', views.delete),  # 捕獲url參數:位置參數
url(r'^delete(?P<bid>\d+)/', views.delete),  # 捕獲url參數:關鍵字參數

def delete(request, bid):
    """刪除一本書籍"""
    # 1.獲取書籍對象
    book = models.BookInfo.objects.get(id=bid)
    # 2.刪除書籍
    book.delete()
    # 3.重定向
    return redirect('/index')

註意,使用關鍵字參數時,視圖中的參數名應該和正則表達式中的參數名一致

 

普通登錄案例

普通登錄案例項目分析

1)顯示出登錄頁面

  • a)設計url,通過瀏覽器訪問 http://127.0.0.1:8000/login 時顯示登錄頁面。
  • b)設計url對應的視圖函數login。
  • c)編寫模板文件login.html。
url 視圖 模板文件
/login login login.html

 

2)登錄校驗功能

  • a)設計url,點擊登錄頁的登錄按鈕發起請求http://127.0.0.1:8000/login_check時進行登錄校驗。
  • b)設計url對應的視圖函數login_check。
  1. 接收表單提交過來的數據。
  2. 進行登錄校驗,若用戶名密碼正確則跳轉到登錄成功頁。若失敗在跳轉到登錄頁面。
  • c)登錄成功後跳轉到首頁。
url 視圖 模板文件
/login_check login_check

 

普通登錄示例代碼 

定義login.html頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="/login_check/" method="post">
    <label for="username">用戶:
        <input type="text" id="username" name="username">
    </label><br />

    <label for="password">密碼:
        <input type="password" id="password" name="password">
    </label><br />
    
    <input type="submit" value="登錄">
</form>

</body>
</html>
index.html

編寫login函數

def login(request):
    """登錄處理函數"""
    return render(request, "booktest/login.html")

配置login和login_check路由

url(r'^login/$', views.login),
url(r'^login_check/$', views.login_check),

編寫login_check函數

def login_check(request):
    # 1.獲取用戶名和密碼
    username = request.POST.get("username")
    password = request.POST.get("password")
    # 2.進行校驗
    # 3.返回應答
    if username == "yifchan" and password == "yifchan":
        return redirect("/index")
    else:
        return HttpResponse("賬號或密碼錯誤")

 

 

HttpReqeust對象

伺服器接收到http協議的請求後,會根據報文創建HttpRequest對象,這個對象不需要我們創建,直接使用伺服器構造好的對象就可以。
視圖的第一個參數必須是HttpRequest對象,即request,在django.http模塊中定義了HttpRequest對象的API。

屬性

下麵除非特別說明,屬性都是只讀的。

path 一個字元串,表示請求的頁面的完整路徑,不包含功能變數名稱和參數部分。
method 一個字元串,表示請求使用的HTTP方法,常用值包括:'GET'、'POST'。
在瀏覽器中給出地址發出請求採用get方式,如超鏈接。
在瀏覽器中點擊表單的提交按鈕發起請求,如果表單的method設置為post則為post請求。
encoding

一個字元串,表示提交的數據的編碼方式。如果為None則表示使用瀏覽器的預設設置,一般為utf-8。

這個屬性是可寫的,可以通過修改它來修改訪問表單數據使用的編碼,接下來對屬性的任何訪問將使用新的encoding值。

GET QueryDict類型對象,類似於字典,包含get請求方式的所有參數。
POST QueryDict類型對象,類似於字典,包含post請求方式的所有參數。
FILES 一個類似於字典的對象,包含所有的上傳文件。
COOKIES 一個標準的Python字典,包含所有的cookie,鍵和值都為字元串。
session 一個既可讀又可寫的類似於字典的對象,表示當前的會話,只有當Django 啟用會話的支持時才可用,詳細內容見"狀態保持"。

 

QueryDict對象

  • 定義在django.http.QueryDict
  • HttpRequest對象的屬性GET、POST都是QueryDict類型的對象
  • 與python字典不同,QueryDict類型的對象用來處理同一個鍵帶有多個值的情況

方法get()

根據鍵獲取值

如果一個鍵同時擁有多個值將獲取最後一個值

如果鍵不存在則返回None值,可以設置預設值進行後續處理

dict.get('',預設值)
# 可簡寫為
dict['']

 

方法getlist()

根據鍵獲取值,值以列表返回,可以獲取指定鍵的所有值
如果鍵不存在則返回空列表[],可以設置預設值進行後續處理

dict.getlist('',預設值)

 

方法dict['鍵']

根據鍵獲取值
和get()方法差不多,但沒有值的時候會報錯;

 

取QueryDict值示例

from django.http.request import QueryDict
q = QueryDict('a=1&b=2&c=3')
q['a']
q['b']
q.get('a')
q.get('c', default="")

應註意使用[]取值時如果沒有值會報錯,而get只會返回一個none,不會報錯,所以一般使用get;

此外,QueryDict和字典的不同之處在於可以一個key對應多個value,但會取後面的那個value,
想要獲取該key所有的value,可以通過dict.getlist('鍵',預設值)進行獲取。

 

 

ajax請求

ajax,即非同步的javascript。在不全部載入某一個頁面部的情況下,對頁面進行局的刷新,ajax請求都在後臺。
圖片,css文件,js文件都是靜態文件。

1)發起ajax請求:jquery發起
2)執行相應的視圖函數,返回json內容
3)執行相應的回調函數。通過判斷json內容,進行相應處理。

 

python和ajax結合使用

因為要引入jquery,一般對於這些靜態文件,我們會創建static文件,將靜態文件放入裡面,在settings文件裡面進行配置。

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] # 設置靜態文件的保存目錄

在static文件夾下新建js,css等文件;
在js中引入jquery文件;
編寫ajax_test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
        {#    綁定btnAjax的click事件#}
            $('#btnAjax').click(function () {
                $.ajax({
                    'url': '/ajax_handle',
                    'type': 'get',
                    'datatype': 'json'
                }).done(function (data) {
                    // 處理後端拿過來的數據
                    // console.log(data.res);
                    if (data.res == '1') {
                        $('#message').show().html("提示信息");
                    }
                })
            })
        })
    </script>
    <style>
        #message {display: none;color: red;}
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax請求">
<div id="message"></div>
</body>
</html>
ajax_test.html

編寫ajax_test函數

def ajax_test(request):
    """返回ajax頁面"""
    return render(request, "booktest/ajax_test.html")

設計ajax_test,ajax_handle的url

url(r'^ajax_test/$', views.ajax_test),
url(r'^ajax_handle/$', views.ajax_handle),

編寫ajax_handle處理函數

def ajax_handle(request):
    """ajax處理函數"""
    return JsonResponse({"res": 1})

關於ajax調試,可以使用瀏覽器的network視窗,如果出現問題,就到network視窗,點擊出錯的請求,再點擊response,就會有報錯詳情了;

 

ajax同步和非同步

同步:等別人執行完再執行;
非同步:不管別人有沒有執行完,就執行;

ajax預設是非同步的,即不等ajax請求返回數據,就執行ajax後面的代碼,如果想要實現ajax通過不,可以添加'async': false:

$.ajax({
    'url': '/ajax_handle',
    'dataType': 'json',
    'async': false, // 同步的ajax請求,預設為True
})

ajax預設是非同步的請求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
            // 綁定btnAjax的click事件
            $('#btnAjax').click(function () {
                console.log("1");
                $.ajax({
                    'url': '/ajax_handle',
                    'type': 'get',
                    'datatype': 'json'
                }).done(function (data) {
                    // 處理後端拿過來的數據
                    console.log("2");
                })
                console.log("3");
            })
        })
    </script>
    <style>
        #message {display: none;color: red;}
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax請求">
<div id="message"></div>
</body>
</html>
ajax非同步示例代碼

這個時候,是預設的非同步ajax,就會依次彈出1,3,2;

 

同步的ajax請求,需要在ajax中添加 'async': false,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
            // 綁定btnAjax的click事件
            $('#btnAjax').click(function () {
                console.log("1");
                $.ajax({
                    'url': '/ajax_handle',
                    'type': 'get',
                    'datatype': 'json',
                    'async': false, // 同步的ajax請求,預設為True
                }).done(function (data) {
                    // 處理後端拿過來的數據
                    console.log("2");
                })
                console.log("3");
            })
        })
    </script>
    <style>
        #message {display: none;color: red;}
    </style>
</head>
<body>
<input type="button" id="btnAjax" value="ajax請求">
<div id="message"></div>
</body>
</html>
ajax同步示例代碼

這個時候,是同步的ajax,就會依次彈出1,2,3;

 

ajax登錄案例

編寫login_ajax.html頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="/static/js/jquery-3.3.1.js"></script>
    <script>
        $(function () {
            // 綁定btnLogin的click事件
            $('#btnLogin').click(function () {
                // 1.獲取用戶輸入的用戶名和密碼
                $username = $('#username').val();
                $password = $('#password').val();
                // 2.攜帶用戶名和密碼,發起ajax請求,login_ajax_check
                $.ajax({
                    'url': '/login_ajax_check/',
                    'type': 'post',
                    'data': {'username': $username, 'password': $password},
                    'datatype': 'json',
                }).done(function (data) {
                    // 登錄成功,{'res': 1}
                    // 登錄失敗,{'res': 0}
                    if (data.res == '0') {
                        console.log("res0");
                        $('#error_message').show()
                    }
                    else {
                        // 登錄成功則跳轉到首頁
                        console.log("res1");
                        location.href = '/index';
                    }
                });
            })
        })
    </script>
    <style>
        #error_message {
            display: none;
            color: red;
        }
    </style>
</head>
<body>

<div>
    <label for="username">用戶:
        <input type="text" id="username" name="username">
    </label><br />

    <label for="password">密碼:
        <input type="password" id="password" name="password">
    </label><br />
    <div id="error_message">賬號名或密碼錯誤</div>

    <input type="button" id="btnLogin" value="登錄">
</div>

</body>
</html>
login_ajax.html

編寫login_ajax函數

def login_ajax(request):
    """返回ajax登錄頁面"""
    return render(request, "booktest/login_ajax.html")

設計login_ajax路由:

url(r'^login_ajax/$', views.login_ajax),

點擊登錄後ajax發送消息給後端路由,

編寫login_ajax_check登錄校驗函數

def login_ajax_check(request):
    # 1.獲取用戶名和密碼
    # 如果是ajax提交的,那麼這裡的get中的值應該和ajax發過來的值一樣;
    username = request.POST.get("username")
    password = request.POST.get("password")
    # 2.進行校驗
    # 3.返回應答
    if username == "yifchan" and password == "yifchan":
        return JsonResponse({"res": 1})
    else:
        return JsonResponse({"res": 0})

設計 login_ajax_check 路由:

url(r'^login_ajax_check/$', views.login_ajax_check),

註意:ajax的請求在後臺,不要返回頁面或重定向,無效;比如當前端發登錄的ajax給後端,後端校驗用戶名

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

-Advertisement-
Play Games
更多相關文章
  • [TOC] Java實現發郵件功能 前言 電子郵件的應用場景非常廣泛,例如新用戶加入,即時發送優惠清單、通過郵件找回密碼、監聽後臺程式,出現異常自動郵件通知等。 本文以網易郵箱為例,通過Java代碼實現發送郵件功能。 開發環境 請參照: "基於SpringBoot構建分模塊項目" 代碼 1. pom ...
  • 轉載註明:https://blog.csdn.net/WantFlyDaCheng/article/details/100078782 一、框架是重點,但別讓人感覺你只會山寨別人的代碼 二、別單純看單機版的框架,適當瞭解些分散式 三、資料庫方面,別就知道增刪改查,得瞭解性能優化 四、Java核心方面 ...
  • 轉載註明:https://blog.csdn.net/WantFlyDaCheng/article/details/100078777 自動代碼 查詢快捷鍵 其他快捷鍵 調試快捷鍵 重構 十大Intellij IDEA快捷鍵 1 智能提示 2 重構 3 代碼生成 4 編輯 5 查找打開 6 其他輔助 ...
  • 單例定義: 一個類只有一個實例,並提供一個全局訪問點。 巧妙利用了編程語言的一些語法規則:構造函數private, 然後提供一個public的方法返回類的一個實例;又方法和返回的類的實例都是static類型,所以只能被類所擁有,而不能被實例化類的對象擁有。這樣一個類就只能有一個實例了。 2. 加”s ...
  • 函數的定義與調用 在Scala中定義函數時,需要定義函數的函數名、參數、函數體。 我們的第一個函數如下所示: def sayHello(name: String, age: Int) = { if (age > 18) { printf("hi %s, you are a big boy\n", n ...
  • JavaFX的對話框主要分為提示對話框和文件對話框兩類,其中提示對話框又分作消息對話框、警告對話框、錯誤對話框、確認對話框四種。這四種對話框都使用Alert控制項表達,並通過對話框類型加以區分,例如AlertType.INFORMATION表示消息對話框,AlertType.WARNIN表示警告對話框 ...
  • 攔截器配置類使用繼承寫法導致jackson的全局配置失效,採用配置類實現WebMvcConfigurer介面解決問題 ...
  • Scala解釋器的使用 ·REPL:Read(取值)-> Evaluation(求值)-> Print(列印)-> Loop(迴圈)。scala解釋器也被稱為REPL,會快速編譯scala代碼為位元組碼,然後交給JVM來執行。 ·計算表達式:在scala>命令行內,鍵入scala代碼,解釋器會直接返回 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...