Django之視圖


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給后端,后端校驗用戶名密碼正確后,不能直接重定向到index頁面,而是返回狀態碼,經過ajax判斷狀態碼后重定向到index頁面,即由前端重定向;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM