Django - 03-Django視圖

[toc]

1 概述

1.1 視圖作用

視圖接受web請求,并響應(yīng)web請求;

1.2 視圖本質(zhì)

視圖就是一個python中的函數(shù);

1.3 響應(yīng)的內(nèi)容

網(wǎng)頁
        重定向
        錯誤視圖    400、404、500
        
JSON數(shù)據(jù)

1.4 響應(yīng)的過程

graph LR
A[<b>用戶在瀏覽器輸入網(wǎng)址</b><br>www.class.com/grade/index.html<br><br><b><i>網(wǎng)址</i></b>]              --> B
B[<b>django獲取網(wǎng)址信息</b><br>去除ip與端口<br>grade/index.html<br><br><b><i>虛擬路徑與文件名</i></b>]  --> C
C[<b>url管理器</b><br>逐個匹配urlconf<br>記錄視圖函數(shù)名<br><br><b><i>視圖函數(shù)名</i></b>]                --> D
D[<b>視圖管理器</b><br>找到對應(yīng)的視圖去執(zhí)行<br>返回結(jié)果給瀏覽器<br><br><b><i>響應(yīng)的數(shù)據(jù)</i></b>]        --> A

2 url配置

2.1 配置流程

1. 指定根級url配置文件
        配置 settings.py 文件中的 ROOT_URLCONF
        ROOT_URLCONF = 'class.urls'
        django默認(rèn)配置好了

2. urlpatterns
        一個url實例列表
        url對象:
                正則表達(dá)式
                視圖名稱
                名稱
                
3. url匹配正則的注意事項
        如果想要從url中獲取一個值,需要對正則加小括號
                url(r'^stupage/(\d)/$', views.stupage),
        匹配正則前方不需要加 / 
        正則前需要加 r 表示字符串不轉(zhuǎn)義

2.2 引入其他url配置

在應(yīng)用中創(chuàng)建 urls.py 配置文件,定義本應(yīng)用的url配置,在 工程/urls.py 文件中使用include()方法

        from django.conf.urls import url, include
        from django.contrib import admin
        urlpatterns = [
            url(r'^', include('myapp.urls', namespace='myapp'))
        ]

匹配過程:
        工程/urls.py --> 應(yīng)用/urls.py

2.3 URL的反向解析

namespace='myapp'
name='myapp'

情景:
        如果修改了urls.py 中的正則表達(dá)式,則對應(yīng)的模板中的 鏈接也都要做對應(yīng)修改,非常影響工作;

概述:
        如果在視圖、模板中使用了硬編碼鏈接,在url配置發(fā)生改變時,動態(tài)生成鏈接地址;
        
解決:
        在使用鏈接時,通過url配置的名稱,動態(tài)生成url地址;
        
作用:
        使用url模板

3 視圖函數(shù)

3.1 定義視圖

本質(zhì):
        一個函數(shù);
        
視圖參數(shù):
        一個HttpRequest的實例,里面包含來自瀏覽器的全部內(nèi)容;
        通過正則表達(dá)式獲取的參數(shù);
        
位置:
        一般在views.py文件下定義;

3.2 錯誤視圖

400視圖     錯誤出現(xiàn)在客戶的操作
500視圖     在視圖代碼中出現(xiàn)錯誤(服務(wù)器代碼)

404視圖
        找不到網(wǎng)頁(url匹配不成功)時返回
        在template下定義404.html
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>404</title>
                </head>
                <body>
                    <h1>頁面丟失</h1>
                    <h2>{{ request_path }}</h2>
                </body>
                </html>
                
                #------------------------------------
                request_path        導(dǎo)致錯誤的網(wǎng)址
                
        配置settings.py
                DEBUG       如果為True,永遠(yuǎn)不會調(diào)用404.html
                ALLOWED_HOSTS = ['*']

4 HttpRequest對象

4.1 概述

服務(wù)器接受http請求后,會根據(jù)報文創(chuàng)建一個HttpRequest對象;
視圖的第一個參數(shù)就是 HttpRequest 對象;
Django創(chuàng)建的對象,之后傳遞給視圖;

4.2 屬性

path
        請求的完整路徑(不包括域名和端口);
        
method
        表示請求的方式,常用的有GET、POST;
        
encoding
        表示瀏覽器提交的數(shù)據(jù)的編碼方式;
        一般為utf-8;
        
GET
        類似字典的對象,包含了get請求的所有參數(shù);
        
POST
        類似字典的對象,包含了post請求的所有參數(shù);
        
FILES
        類似字典的對象,包含了所有上傳的文件;
        
COOKIES
        字典,包含所有的cookie
        
session
        類似字典的對象,表示當(dāng)前的會話;

4.3 方法

is_ajax()
        如果是通過XMLHttpRequest發(fā)起的,返回True;

4.4 QueryDict對象

request對象中的GET、POST都屬于QueryDict對象;

方法:
        get()
                作用:根據(jù)鍵獲取值
                只能獲取一個值
                www.class.com/abc?a=1&b=2&c=3       有一個a
        
        getlist()
                將鍵的值以列表的形式返回
                可以獲取多個值
                www.class.com/abc?a=1&a=2&c=3       有兩個a

4.5 GET屬性

獲取瀏覽器傳遞給服務(wù)器的數(shù)據(jù);

http://127.0.0.1:8000/get1?a=1&b=2&c=3
        def get1(request):
            a = request.GET.get('a')
            b = request.GET.get('b')
            c = request.GET.get('c')
            return HttpResponse(a + '|' + b  + '|'+ c)
            
http://127.0.0.1:8000/get2?a=1&a=2&c=3
        def get2(request):
            a = request.GET.getlist('a')
            a1 = a[0]
            a2 = a[1]
            c = request.GET.get('c')
            return HttpResponse(a1 + '|' + a2 + '|' + c)

4.6 POST屬性

使用表單
        編輯一個表單模板 register.html:
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>注冊</title>
                </head>
                <body>
                    <form action="register/" method="post">
                        姓名:
                        <input type="text" name="name" value="">
                        <hr>
                        性別:
                        <input type="radio" name="gender" value="1">男
                        <input type="radio" name="gender" value="10">女
                        <hr>
                        年齡:
                        <input type="text" name="age" value="">
                        <hr>
                        愛好:
                        <input type="checkbox" name="hobby" value="power">權(quán)利
                        <input type="checkbox" name="hobby" value="money">金錢
                        <input type="checkbox" name="hobby" value="boy">美男
                        <input type="checkbox" name="hobby" value="girl">美女
                         <hr>
                        <input type="submit", value="注冊">
                    </form>
                </body>
                </html>
                
        編輯urls.py:
                url(r'^showregister/$', views.showregister),
                url(r'^showregister/register/$', views.register),
                
        編輯視圖 views.py:
                def showregister(request):
                    return render(request, 'myapp/register.html')
                def register(request):
                    name = request.POST.get('name')
                    gender = request.POST.get('gender')
                    age = request.POST.get('age')
                    hobby = request.POST.getlist('hobby')
                    print(name)
                    print(gender)
                    print(age)
                    print(hobby)
                    return HttpResponse('resgister')
                    
關(guān)閉CSRF
        注釋掉 settings.py 中的 MIDDLEWARE: 'django.middleware.csrf.CsrfViewMiddleware'
                MIDDLEWARE = [
                    'django.middleware.security.SecurityMiddleware',
                    'django.contrib.sessions.middleware.SessionMiddleware',
                    'django.middleware.common.CommonMiddleware',
                    # 'django.middleware.csrf.CsrfViewMiddleware',
                    'django.contrib.auth.middleware.AuthenticationMiddleware',
                    'django.contrib.messages.middleware.MessageMiddleware',
                    'django.middleware.clickjacking.XFrameOptionsMiddleware',
                ]

5 HttpResponse對象

5.1 概述

作用:
        給瀏覽器返回數(shù)據(jù);

HttpRequest對象是由Django創(chuàng)建的,HttpResponse對象是有程序員創(chuàng)建的

5.2 返回用法

不調(diào)用模板,直接返回數(shù)據(jù)
        def index(request):
            return HttpResponse('Hahahahaha')

調(diào)用模板,使用 render() 方法:
        原型:
                render(request, templateName[, context])
        
        作用:
                結(jié)合數(shù)據(jù)和模板,返回完整的HTML頁面;
                
        參數(shù):
                request         請求對象體
                templateName    模板路徑
                context         傳遞給需要渲染在模板的數(shù)據(jù)
                
        示例:
                def grade(request):
                    gradeList = Grade.objects.all()
                    return render(request, 'myapp/grade.html', {'grade': gradeList})

5.3 屬性

content
        表示返回的內(nèi)容的類型

character
        返回的數(shù)據(jù)的編碼格式
        
status_code
        響應(yīng)狀態(tài)碼
                200
                304
                404
                
content-tpye
        指定輸出的MIME類型
        
栗子:
        url(r'^showresponse/$', views.showresponse),
        
        def showresponse(request):
            res = HttpResponse()
            res.content = b'nice'
            print(res.content)
            print(res.charset)
            print(res.status_code)
            print(res.content-type)
            return res

5.4 方法

init
        使用頁面內(nèi)容實例化HttpResponse對象

writr(content)
        以文件的形式寫入
        
flush
        以文件的形式輸出緩沖區(qū)
        
set_cookie(key, value, max_age=None, exprise=None)
        

delete_cookie(key)
        刪除 cookie
        注意: 如果刪除一個不存在的cookie,什么都不會發(fā)生;

栗子:
        url(r'^cookietest/$', views.cookietest)
        
        def cookietest(request):
            res = HttpResponse()
            # res.set_cookie("class", "good")
            cookie = request.COOKIES
            res.write("<h1>" + cookie['class'] + "</h1>")
            return res

5.5 子類 HttpResponseRedirect

功能:
        重定向,服務(wù)器端的跳轉(zhuǎn);

栗子:
        url(r'^redirect1/$', views.redirect1),
        url(r'^redirect2/$', views.redirect2),

        from django.http import HttpResponseRedirect
        def redirect1(request):
            print('我是重定向前的redirect1')
            return HttpResponseRedirect('/redirect2')
        
        def redirect2(request):
            return HttpResponse('我是重定向后的redirect2')
            
            
簡寫:  redirect(to)    to 推薦使用反向解析
        
        from django.shortcuts import redirect
        def redirect1(request):
            print('我是重定向前的redirect1')
            return redirect('/redirect2')
        
        def redirect2(request):
            return HttpResponse('我是重定向后的redirect2')

5.6 子類 JsonResponse

返回json數(shù)據(jù),一般用于異步請求(ajax)

__init__(self, data)
        data        字典對象

注意:
        Content-type 類型為 application/json

6 狀態(tài)保持 session

6.1 概述

HTTP協(xié)議是無狀態(tài)的,每次請求都是一次新的請求,不記得以前的請求;

客戶端與服務(wù)器端的一次通信就是一次會話;

實現(xiàn)狀態(tài)保持,在客戶端或者服務(wù)器端存儲有關(guān)會話數(shù)據(jù);

存儲的方式:
        cookie      所有的數(shù)據(jù)都存儲在客戶端,不要存儲敏感數(shù)據(jù);
        session     所有的數(shù)據(jù)存儲在服務(wù)端,在客戶端用cookie存儲session_id;

狀態(tài)保持的目的:
        在一段時間內(nèi),跟蹤請求者的狀態(tài),可以實現(xiàn)跨頁面訪問當(dāng)前請求者的數(shù)據(jù);
        
注意:
        不同的請求者之間不會共享這個數(shù)據(jù);

6.2 啟用session

settings.py中:
        INSTALLED_APPS
                'django.contrib.sessions',
        MIDDLEWARE
                'django.contrib.sessions.middleware.SessionMiddleware',

默認(rèn)啟用

6.3 使用session

啟用session后,每個HttpRequest對象,都有一個session屬性,就是一個類似字典的對象;

get(key, default=None)
        根據(jù)鍵獲取session值
        
clear()
        清空所有的會話
        
flush()
        刪除當(dāng)前的會話并刪除會話的cookie
        
栗子:
        歡迎頁 --登錄--> 登錄頁 --輸入用戶名--> 歡迎頁,顯示登錄名
        歡迎頁 --退出登錄--> 清理session
                urls.py
                        url(r'^main/$', views.main),
                        url(r'^login/$', views.login),
                        url(r'^showmain/$', views.showmain),
                        url(r'^quit/$', views.quit),
                
                views.py
                        from django.shortcuts import redirect
                        def main(request):
                            # 取session
                            username = request.session.get('name', '游客')
                            return render(request, 'myapp/main.html', {"username": username})
                        
                        def login(request):
                            return render(request, 'myapp/login.html')
                        
                        def showmain(request):
                            username = request.POST.get('username')
                            # 存儲session
                            request.session['name'] = username
                            return redirect('/main')
                            
                        from django.contrib.auth import logout
                        def quit(request):
                            # 清除session
                            # logout(request)
                            request.session.clear()
                            return redirect('/main')
                    
                main.html
                        <head>
                            <meta charset="UTF-8">
                            <title>我的</title>
                        </head>
                        <body>
                            <h1>歡迎:{{ username }}</h1>
                            <a href="/login/">登錄</a>
                            <a href="/quit/">退出登錄</a>
                            
                        </body>
                    
                login.html
                        <head>
                            <meta charset="UTF-8">
                            <title>登錄</title>
                        </head>
                        <body>
                            <form action="/showmain/" method="post">
                                <input type="text" name="username"><br>
                                <input type="submit" value="登錄">
                            </form>
                        </body>

6.4 設(shè)置過期時間

set_expiry(value)
        如果不設(shè)置,默認(rèn)是兩個星期后過期;
        
        整數(shù):  
                value填10,則是10秒后過期;
                
                def showmain(request):
                    username = request.POST.get('username')
                    # 存儲session
                    request.session['name'] = username
                    request.session.set_expiry(10)
                    return redirect('/main')
                    
        時間對象
        
        0
                關(guān)閉瀏覽器是失效
        
        None
                永不過期

6.5 存儲session的位置

在 settings.py 中增加 SESSION_ENGINE 配置;

數(shù)據(jù)庫
        默認(rèn)存儲在數(shù)據(jù)庫中;
        SESSION_ENGINE = 'django.contrib.sessions.backends.db'
        
緩存
        只存出在本地內(nèi)存中,如果丟失,不能找回;
        SESSION_ENGINE = 'django.contrib.sessions.backends.cached'


數(shù)據(jù)庫和緩存
        優(yōu)先從本地緩存中讀取,讀取不到,再去數(shù)據(jù)庫中獲取;
        SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

6.6 使用redis緩存session

pip install django-redis-session

配置redis:
        在settings.py追加:
                SESSION_ENGINE = 'redis_sessions.session'
                SESSION_REDIS_HOST = 'localhost'
                SESSION_REDIS_PORT = 6379
                SESSION_REDIS_DB = 0
                SESSION_REDIS_PASSWORD = 'admin'
                SESSION_REDIS_PREFIX = 'session'

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容