[Python自學] day-18 (2) (MTV架構、Django框架、模板語言)

1、實現一個簡單的Web服務器

使用Python標準庫提供的獨立WSGI服務器來實現MVC架構。css

首先,實現一個簡單的Web服務器:html

from wsgiref.simple_server import make_server # 每當一個請求鏈接,這個函數被調用一次
def RunServer(environ, start_response): # 返回響應頭、狀態等
    start_response('200 OK', [('Content-Type', 'text/html')]) # 返回響應體數據
    return ['<h1>Hello World</h1>'.encode('utf-8'), ] def main(): # 建立一個服務器,監聽端口爲8000,綁定運行函數爲RunServer()
    httpd = make_server('', 8000, RunServer) print('Servering HTTP in port 8000..') # 無線循環
 httpd.serve_forever() if __name__ == '__main__': main()

 

添加處理URL的功能:前端

from wsgiref.simple_server import make_server import time # 對應'/index'的處理函數
def handle_index(): return ["<h1>Index Page...</h1>".encode('utf-8'), ] # 對應'/register'的處理函數
def handle_register(): return ["<h1>Register Page...</h1>".encode('utf-8'), ] # 對應'/date'的處理函數
def handle_date(): return [("<h1>Date:" + str(time.time()) + "</h1>").encode('utf-8'), ] # 全局字典,手工添加映射關係
URL_DICT = { '/index': handle_index, '/register': handle_register, '/date': handle_date } # 每當一個請求鏈接,這個函數被調用一次
def RunServer(environ, start_response): # 返回響應頭、狀態等
    start_response('200 OK', [('Content-Type', 'text/html')]) # 檢查字典中是否存在映射關係,若是有則調用對應的函數,若是沒有則返回404
    current_url = environ['PATH_INFO'] func = None if current_url in URL_DICT: func = URL_DICT[current_url] if func: return func() else: return ['<h1>404 Error Page..</h1>'.encode('utf-8'), ] def main(): # 建立一個服務器,監聽端口爲8000,綁定運行函數爲RunServer()
    httpd = make_server('', 8000, RunServer) print('Servering HTTP in port 8000..') # 無線循環
 httpd.serve_forever() if __name__ == '__main__': main()

上述代碼添加了處理URL的功能,能夠根據不一樣的URL返回不一樣的數據。python

主要的關鍵點:jquery

1.使用一個全局的字典來存放URL和處理函數之間的映射關係(注意,這裏的映射關係是寫死的,也就是說咱們要添加一個頁面,就得手工往字典中添加一個映射關係)nginx

2.每一個URL使用一個獨立的函數進行處理sql

 

咱們能夠經過處理函數讀取index.html文件中的內容,而後將其返回數據庫

對handle_index()進行修改:django

# 對應'/index'的處理函數
def handle_index(): data = b'' with open('index.html', 'rb') as f: data = f.read() return [data, ]

添加一個index.html文件:windows

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index Page</title>
</head>
<body>
    <h1>This is @user Index Page...</h1>
</body>
</html>

這裏的@user能夠用數據庫讀取的內容來替換。

 

2、MVC架構

咱們參考第一節中的代碼,將其修改成MVC架構。

修改項目的目錄結構,添加View、Controller和Model三個目錄:

Controller:用於存放業務處理邏輯代碼,例如前面的handle_index()等。功能例如讀取Html文件,替換數據,返回數據等。

Model:用於存放數據庫操做等代碼。這些代碼用於讀取數據庫數據,並將數據返回給Controller。

View:用於存放前端頁面文件,例如Html等。主要是Html模板。

 

咱們將index.html這類靜態文件放入View目錄中。

將handle處理函數所有分離到handler.py中,而後放到Controller中:

import time from Model import read_db # 對應'/index'的處理函數
def handle_index(): data = b'' with open('Template/index.html', 'rb') as f: data = f.read() user = read_db.get_user() print(user)
   # 將index.html中的@user替換爲從數據庫中獲取的數據,這裏例如"Leo" data
= data.replace(b"@user", user.encode('utf-8')) return [data, ] # 對應'/register'的處理函數 def handle_register(): return ["<h1>Register Page...</h1>".encode('utf-8'), ] # 對應'/date'的處理函數 def handle_date(): return [("<h1>Date:" + str(time.time()) + "</h1>").encode('utf-8'), ]

這樣,將全部的文件分類放置。將整個項目劃分爲MVC三個層面,叫作MVC架構

 

3、MTV架構

對應MVC架構,還有一種叫作MTV架構,實際上他們是同樣的:

架構名稱 數據庫處理 模板文件 業務處理
MVC Model View Controller
MTV Model Template View

如上表所示,MVC和MTV架構只是名字的對應關係不同。

在MTV中,html文件屬於Template,而業務處理叫作View。

 

經過修改項目目錄結構,將MVC修改成MTV結構:

 

4、安裝Django

使用PYTHON_HOME/Scripts/pip.exe來安裝Django:

# 使用清華源安裝django pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple

 

將PYTHON_HOME/Scripts添加到環境變量:

 

使用django-admin命令來建立一個django項目:

D:\>django-admin startproject firstsite

其中firstsite是django項目名稱,咱們在D盤根目錄下執行命令,項目則存在於這個目錄下。

 

進入生成的firstsite目錄,咱們能夠看到:

 

使用manage.py運行django程序:

D:\firstsite>python manage.py runserver 127.0.0.1:8001 Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. December 16, 2019 - 13:25:34 Django version 3.0, using settings 'firstsite.settings' Starting development server at http://127.0.0.1:8001/
Quit the server with CTRL-BREAK.

訪問127.0.0.1:8001,能夠看到如下頁面,表示django運行成功:

 

除了使用django-admin命令建立django程序,還能夠直接在Pycharm中建立:

Pycharm會建立一個同樣的django程序:

 

點擊Pycharm右上角的運行按鈕便可運行django:

 注意,這裏必定要選擇項目名運行,不然運行報錯。若是要修改運行的host和port,則進入Edit Configurations中進行修改。

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. December 16, 2019 - 14:03:12 Django version 3.0, using settings 'secondsite.settings' Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

 

5、django目錄介紹

1.用Pycharm打開已經建立好的django程序

 

2.django程序目錄結構

firstsite -- firstsite # 對整個程序進行配置的目錄 -- __init__ -- settings.py # 配置文件 -- urls.py # URL對應關係 -- wsgi.py   # 遵循WSGI規範,默認使用的是wsgiref,上線的話要使用uwsgi + nginx -- db.sqlite3 -- manage.py # 管理Django程序,例如建立一個APP:python manage.py startapp xxx django的ORM:python manage.py makemigrations python manage.py migrate

 

6、django中的APP

1.APP概念

咱們建立一個django工程之後,咱們能夠建立多個APP,每一個APP表明着一個子模塊,如圖:

這個運維平臺看作一個django project,而下面的 資產、配管、私有云等都是一個APP。

 

2.建立一個APP

在Pycharm中使用命令行來建立(Pycharm最下方能夠選擇Terminal頁籤):

 

執行命令:

d:\Dev_apps\Anaconda5.3.0\python.exe manage.py startapp cmdb

其中,cmdb是APP名稱。

固然,咱們也可使用windows cmd命令窗口執行。

 

建立完畢後,咱們能夠看到生成了一個cmdb目錄:

3.測試使用APP

在cmdb APP中,咱們找到Views文件:

 

而後在其中添加請求處理函數:

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse # /cmdb.html請求的處理函數
def cmdb_home(request): return HttpResponse("<h1>CMDB home page..</h1>")

在secondsite/urls.py中添加一條映射關係:

from cmdb import views urlpatterns = [ path('admin/', admin.site.urls), path('cmdb.html/', views.cmdb_home), ]

運行django程序,訪問頁面:

 

7、APP的目錄結構

 

1.miragtions目錄:

在 [Python自學] day-12 (Mysql、事務、索引、ORM) 中,咱們使用過ORM框架 SQLAlchemy。

在SQLAlchemy中,咱們能夠建立表、增刪改查數據等,但沒法對錶結構進行修改

但在django框架中,他所提供的ORM功能很是厲害,能夠提供很細緻化的操做,例如刪除表的列、修改列的數據類型、數據長度等等。

 

咱們在某個Django APP目錄中能夠看到一個叫作migrations的目錄

這個目錄是用來記錄數據庫操做的,當咱們作了修改表結構等數據庫操做後,django會自動在migrations目錄中生成記錄,咱們沒法人工干預。

2. admin.py

該目錄是django爲咱們提供的數據庫後臺管理,能夠用不多的代碼實現一個功能比較完整的後臺管理頁面。效果以下:

默認狀況下,django爲咱們提供了一個輕量級數據庫Sqlite3:

3.apps.py

用於配置當前APP

4.models.py

就是django給咱們提供的ORM,咱們在裏面寫指定的類,而後經過manage.py makemigrations和manage.py migrate就能夠建立表和修改表結構(會在migrations目錄中產生記錄文件)。

5.tests.py

單元測試

6.views.py

業務邏輯代碼

 

8、實現簡單的login頁面

在cmdb APP中實現簡單的Login頁面。

1.在urls.py中添加相應的映射關係

from cmdb import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), ]

2.在工程的根目錄下建立一個目錄叫templates

 

3.在templates目錄下建立login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <style> label{ width: 80px; text-align: right; display: inline-block;
        }
    </style>
</head>
<body>
    <form action="/login" method="post">
        <p>
            <label for="username">用戶名:</label>
            <input id="username" type="text" />
        </p>
        <p>
            <label for="password">密碼:</label>
            <input id="password" type="password"/>
            <input type="submit" value="提交"/>
        </p>
    </form>
</body>
</html>

4.在cmdb/views.py中寫業務邏輯代碼

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse def login(request): f = open("templates/login.html", 'r', encoding="utf-8") data = f.read() return HttpResponse(data)

在業務代碼中,咱們使用open()打開html文件,讀取內容並返回給客戶端。

可是若是咱們有不少頁面,則每一個都要手工打開文件讀取。Django爲咱們提供了相應的處理方法。

5.使用render來打開html模板

修改views.py中的業務邏輯代碼:

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render def login(request): return HttpResponse(render(request, 'login.html'))

從django.shortcuts中導入render,而後使用render來讀取templates/login.html文件。

注意:這裏咱們沒有使用templates/login.html路徑,而是直接使用login.html。render()方法之因此能直接找到login.html文件,是由於在setting.py文件中對模板路徑的默認配置就是templates。以下:

# setting.py文件
 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]

配置文件中的BASE_DIR就是django工程的根目錄(這裏是secondsite)。這裏將BASE_DIR和'templates'拼接在一塊兒做爲模板的DIR。

6.訪問/login

 

9、靜態文件處理

當咱們要在項目中添加靜態文件是,例如css、js、圖片等。

1.在項目根目錄下建立目錄static

 

2.將須要的靜態文件拷貝到static目錄中

 

其中commons.css內容以下:

.common{ background-color: #eeeeee;
}

3.在login.html中使用css文件和jQuery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <link rel="stylesheet" href="/static/commons.css"/>
    <style> label{ width: 80px; text-align: right; display: inline-block;
        }
    </style>
</head>
<body class="common">
    <form action="/login" method="post">
        <p>
            <label for="username">用戶名:</label>
            <input id="username" type="text" />
        </p>
        <p>
            <label for="password">密碼:</label>
            <input id="password" type="password"/>
            <input type="submit" value="提交"/>
        </p>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
</body>
</html>

4.訪問/login報錯404

 

當頁面在請求/static/commons.css和/static/jquery-1.12.4.js時報404錯誤,說明資源爲找到。

有兩種解決方法:

1) 在urls中添加映射關係(能夠實現,但不能這麼作,靜態文件django能夠專門處理)

2) 在setting中配置靜態文件的路徑(正解)

5.在settings中配置靜態文件路徑

在settings.py配置文件的最後添加如下代碼:

STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'),  # 這裏必須有逗號
)

6.再次訪問/login

頁面訪問正常,而且background-color已經變爲灰色(commons.css中指定的)。

7.填寫表單並提交報錯

 這是由於咱們的表單提交的目的地是/login。

解決方法一:urls.py中的匹配字符串爲"login/",因此表單提交地址應該修改成action="/login/"

解決方法二:urls.py中修改成"login"action="/login"

這樣對應起來,才能匹配。

 

8.再次提交報錯

 

這是CSRF(跨站點請求僞造)錯誤。參照下一節django配置,將CSRF相關配置註釋。

 

10、Django配置

以上章節中已經描述了django的兩項配置:

1)對templates路徑的配置

2)對static路徑的配置

 

1.對CSRF進行配置:

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', ]

在settings.py中將csrf相關的配置項註釋掉。

 

2.配置Django時區:

若是不進行時間配置,Django默認時間比上海時間延後8小時。

在setting中配置時間:

# 將時區修改成上海 # TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

#將USE_TZ修改成false # USE_TZ = True
USE_TZ = False

 

 

11、獲取請求參數

在咱們實現的請求處理業務邏輯代碼中,咱們能夠獲取來自客戶端請求的全部參數:

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render def login(request): return HttpResponse(render(request, 'login.html'))

這些請求參數,都經過 client-->Webserver-->wsgi-->django 將其做爲函數參數傳遞到被調用的login()函數中。

咱們經過request就能夠獲取到客戶端的全部參數

 

1.經過參數判斷請求類型

# cmdb views.py

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render def login(request): if request.method == 'POST': print("Post") elif request.method == 'GET': print('Get') return HttpResponse(render(request, 'login.html'))

當咱們第一次訪問/login時,後臺會打印"GET",當咱們提交表單是,後臺會打印"POST"。

 

2.獲取POST提交的數據

POST提交的數據是以字典形式組織的,因此,首先要在html表單中爲<input>標籤指定name屬性做爲key。

<body class="common">
    <form action="/login/" method="post">
        <p>
            <label for="username">用戶名:</label>
            <input id="username" type="text" name="user"/>
        </p>
        <p>
            <label for="password">密碼:</label>
            <input id="password" type="password" name="pwd"/>
            <input type="submit" value="提交"/>
        </p>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
</body>

而後在後臺經過request獲取POST數據:

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render def login(request): if request.method == 'POST': # username = request.POST['user'] # 儘可能不要用這種方式,由於user若是不存在,則會報錯
        username = request.POST.get('user', None) password = request.POST.get('pwd', None) print("username : %s\npassword : %s" % (username, password)) elif request.method == 'GET': print('Get') return HttpResponse(render(request, 'login.html'))

 

3.驗證數據並跳轉

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect def login(request): if request.method == 'POST': username = request.POST.get('user', None) password = request.POST.get('pwd', None) # 驗證user和pwd,若是正確,則跳轉到www.baidu.com
        if username == 'leokale' and password == '123456': return redirect('http://www.baidu.com') elif request.method == 'GET': print('Get') return HttpResponse(render(request, 'login.html'))

這裏的跳轉要使用return redirect("http://www.baidu.com")

 

4.提交錯誤數據,返回錯誤消息

如下代碼實現了錯誤消息提示,但頁面會刷新(其實是返回了一個新的頁面,包含了錯誤信息),之後可使用Ajax異步請求來實現錯誤提示。

1)在html中,添加錯誤信息的標籤

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <link rel="stylesheet" href="/static/commons.css"/>
    <style> label{ width: 80px; text-align: right; display: inline-block;
        } .error_span{ color: red; }
    </style>
</head>
<body class="common">
    <form action="/login/" method="post">
        <p>
            <label for="username">用戶名:</label>
            <input id="username" type="text" name="user"/>
            <span class="error_span">{{ user_error }}</span>
        </p>
        <p>
            <label for="password">密碼:</label>
            <input id="password" type="password" name="pwd"/>
            <input type="submit" value="提交"/>
            <span class="error_span">{{ pwd_error }}</span>
        </p>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
</body>
</html>

2)驗證user和pwd錯誤時,django自動替換錯誤信息

from django.shortcuts import render # Create your views here.
from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect def login(request): if request.method == 'POST': username = request.POST.get('user', None) password = request.POST.get('pwd', None) # 驗證user和pwd,若是正確,則跳轉到www.baidu.com
        if username == 'leokale' and password == '123456': return redirect('http://www.baidu.com') user_error_msg = '' pwd_error_msg = ''
        if username != 'leokale': user_error_msg = "帳號不存在"
        if password != '123456': pwd_error_msg = "密碼不正確"
        # 當user或pwd錯誤時,django自動使用第三個參數字典中的數據對html中的{{ xxx }}進行替換
        return HttpResponse(render(request, 'login.html', {"user_error": user_error_msg, "pwd_error": pwd_error_msg})) elif request.method == 'GET': print('Get') return HttpResponse(render(request, 'login.html'))

訪問/login,提交錯誤的數據,效果以下:

 

 

12、實現簡單後臺管理功能(利用Django模板語言)

請求後臺管理頁面:http://127.0.0.1/home

1.在urls.py中添加映射關係

from cmdb import views urlpatterns = [ path('admin/', admin.site.urls), path('login', views.login), path('home', views.home),  # 後臺管理頁面映射,映射到cmdb.views.home方法
]

2.home.html頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home</title>
</head>
<body style="margin: 0">
    <div style="height: 48px;background-color: #dddddd"></div>
    <div>
        <!-- 若是用戶點擊添加按鈕,則使用post提交表單 -->
        <form action="/home" method="post">
            <input type="text" name="username"/>
            <input type="text" name="email"/>
            <input type="text" name="gender"/>
            <input type="submit" value="添加"/>
        </form>
    </div>
    <div>
        <!-- 在table中使用模板語言進行循環,獲取user_list中的數據(來自後臺render函數的第三個參數) -->
        <table> {% for row in user_list %} <tr>
                    <td>{{ row.username }}</td>
                    <td>{{ row.email }}</td>
                    <td>{{ row.gender }}</td>
                </tr> {% endfor %} </table>
    </div>
</body>
</html>

在前臺html代碼中,<table>標籤中的數據是動態生成的(來自後臺讀取全局列表的數據,模擬數據庫操做),因此在render返回home.html頁面數據時要對<table>的內容進行替換。

這裏使用模板語言,{% %}中使用循環語句{{ }}中進行取值

 

3.在cmdb APP的views.py中寫請求處理函數

# 所有列表,用於用戶數據(模擬數據庫)
USER_LIST = [ {'username': 'Alex', 'email': 'alex@163.com', 'gender': 'Male'}, ] # 後臺管理頁面
def home(request): # 若是是post請求,說明是用戶點擊添加按鈕提交了表單
    if request.method == 'POST': # 獲取表單中的值,而後添加到列表中(模擬數據庫)
        user = request.POST.get('username', None) email = request.POST.get('email', None) gender = request.POST.get('gender', None) content = {'username': user, 'email': email, 'gender': gender} USER_LIST.append(content) # 返回home頁面信息
    return render(request, 'home.html', {'user_list': USER_LIST})

當請求是POST類型時,說明用戶提交了新的用戶數據,使用request獲取數據,並存放到列表(模擬數據庫)中。而後將列表中的所有數據做爲參數交給django框架,框架對home.html進行替換後返回給瀏覽器。

 

十3、Django框架中請求的生命週期

 

 

 一個非靜態資源請求的URL,生命週期通常如上圖所示:

1.客戶端發送請求給服務器(圖中省略),服務器將請求交給django的路由系統(對應urls.py)

2.路由系統判斷是否存在對應的映射,若是存在,則找到並執行對應的視圖方法(對應APP中的views.py中的函數或類)

3.視圖方法根據業務需求,從數據庫等存儲中獲取業務數據,並使用指定的模板文件(對應html文件)來渲染顯示效果(即便用業務數據替換html中指定部分)

4.返回合併好的數據給客戶端(瀏覽器)

 

十4、Django基礎內容總結

1.建立Django工程:

使用命令行:django-admin startproject pro_name

或者使用pycharm建立

 

2.建立APP

使用命令行:python manage.py startapp app_name

 

3.配置Django

配置靜態文件目錄:settings.py

最後添加:

STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )

配置模板文件目錄(默認是templates):settings.py

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]

禁用CSRF認證(防止post提交403錯誤):settings.py

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', ]

 

4.定義路由規則

在urls.py中添加訪問URL於視圖函數之間的映射關係

  例如:"login" ---> func_name

 

5.定義視圖函數

在app的views.py中定義視圖函數

def func_name(request): if request.method == 'POST': data = request.POST.get('data_name', None) pass
    elif request.method == 'GET': data = request.GET.get('data_name', None) pass
    return render(request, 'xxx.html', {'data_key': data_value})

返回字符串:

return HttpResponse("字符串")

返回模板:

return render(request,'xxx.html',{替換數據字典})

重定向:

return redirect('/login')  # 這裏的"/"表示本地,即httP://127.0.0.1/
return redirect('http://www.baidu.com') # 外部url

 

十5、模板渲染(模板語言)

在Django中存在一套特殊的模板語言:

在settings.py中能夠看到:

TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]

Django提供的默認模板語言叫作DjangoTemplates,這套模板語言可能存在一些侷限性,咱們能夠將其修改成Jinjia2模板語言:

'BACKEND': 'django.template.backends.jinja2.Jinja2',

可是在這裏,咱們仍是先學習默認的模板語言*(^。^)**。如下都是默認模板語言,Jinjia2之後再學習。

 

在使用render返回數據時,Django會將數據和模板合併

return render(request, 'index.html', {'current_user': 'Leo', 'user_list': ['Alex', 'Eric', 'Jone', 'Leo'], 'user_dict': {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}, 'age': 18 })

 

在index.html中使用{{ username }}就能夠獲取到user的值,並自動替換在相應的位置:

<div>{{ username }}</div>

替換後變爲:

<div>Leo</div>

 

index.html中使用循環獲取user_list中的值:

<ul> {% for row in user_list %} <li>{{ row }}</li> {% endfor %} </ul>

獲取列表中的某個值:

<div>{{ user_list.2 }}</div>  <!-- 獲取user_list中的第2個值 -->
<div>{{ user_list.3 }}</div>  <!-- 獲取user_list中的第3個值 -->

 

index.html中循環獲取user_dict中的值:

<!-- 獲取全部key -->
<ul> {% for row in user_dict.keys %} <li>{{ row }}</li> {% endfor %} </ul>
<!-- 獲取全部value -->
<ul> {% for row in user_dict.values %} <li>{{ row }}</li> {% endfor %} </ul>
<!-- 獲取全部key和value -->
<ul> {% for key,value in user_dict.items %} <li>{{ key }} <---> {{ value }}</li> {% endfor %} </ul>

經過key獲取字典中的值:

<div>{{ user_dict.k1 }}</div>  <!-- 獲取字典中鍵爲k1對應的值-->
<div>{{ user_dict.k2 }}</div>  <!-- 獲取字典中鍵爲k2對應的值-->

 

循環計數:

若是想在循環中打印循環的次數(count),可使用如下方式:

<ul> {% for row in user_list %} <li>{{ forloop.counter }}</li>  <!-- 從1開始計數 -->
        <li>{{ forloop.counter0 }}</li>  <!-- 從0開始計數 -->
        <li>{{ forloop.revcounter }}</li>  <!-- 1開始計數,可是反向排列 -->
        <li>{{ forloop.revcounter0 }}</li>  <!-- 0開始計數,可是反向排列 -->
        <li>{{ forloop.first }}</li>  <!-- 第一次循環爲True,後面全爲False -->
        <li>{{ forloop.last }}</li>  <!-- 第一次循環爲False,後面全爲True --> {% endfor %} </ul>

若是是多層循環:

<ul> {% for outer in user_list %} {% for row in user_list %} <li>{{ forloop.parentloop }}</li>  <!-- 外層循環的6個屬性,以字組織 -->
            <li>{{ forloop.parentloop.counter }}</li>  <!-- 獲取外層循環的次數(1開始計數) --> {% endfor %} {% endfor %} </ul>

 

if判斷語句:

{% if age %} <a>有年齡信息</a> {% if age > 16 %} <a>老男人</a> {% else %} <a>小鮮肉</a> {% endif %} {% else %} <a>沒有年齡信息</a> {% endif %}
相關文章
相關標籤/搜索