Django 是 Python 的一款 Web 框架,本備忘單旨在快速理解 所涉及的主要概念,提供了最常用的 API 示例參考
$ python --version
# Python 3.9.2
$ pip --version
# pip 20.2.3 from c:\python39\lib\site-packages\pip (python 3.9)
如果你沒有安裝 PIP,你可以從這個頁面下載并安裝它:
創建虛擬環境
$ py -m venv myproject # Windows
$ python -m venv myproject # Unix/MacOS
其中包含子文件夾和文件,如下所示
myproject
├┈Include
├┈Lib
├┈Scripts
╰┈pyvenv.cfg
以下命令來激活環境
# Windows:
myproject\Scripts\activate.bat
# Unix/MacOS:
source myproject/bin/activate
提示符中看到以下結果:
# Windows:
(myproject) C:\Users\Your Name>
# Unix/MacOS:
(myproject) ... $
安裝 Django
# Windows:
(myproject) C:\Users\Name>py -m pip install Django
# Unix/MacOS:
(myproject) ... $ python -m pip install Django
$ django-admin startproject myworld
創建了一個 myworld
文件夾,內容如下:
myworld
├┈ manage.py
╰┈ myworld/
├┈ __init__.py
├┈ asgi.py
├┈ settings.py
├┈ urls.py
╰┈ wsgi.py
運行 Django 項目
$ py manage.py runserver # Windows
$ python manage.py runserver # Unix/MacOS
打開一個新的瀏覽器窗口并在地址欄中輸入 127.0.0.1:8000
(myproject) C:\Users\Your Name>django-admin --version
# 4.0.3
$ py manage.py startapp members
項目中創建了一個名為 members
的文件夾,內容如下:
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ migrations/
┆ ╰┈ __init__.py
├┈ __init__.py
├┈ admin.py
├┈ apps.py
├┈ models.py
├┈ tests.py
╰┈ views.py
首先,看一下名為 views.py
的文件。這是我們收集發送回正確響應所需的信息的地方。
Django
接收 URL,檢查 urls.py
文件,并調用與 URL 匹配的視圖。views.py
中的視圖檢查相關模型。models.py
文件中導入的。HTML
和 Django
標記,并使用數據將完成的 HTML
內容返回給瀏覽器Django 視圖是接受 http
請求并返回 http
響應的 Python
函數,就像 HTML
文檔一樣。
使用 Django
的網頁充滿了不同任務和任務的視圖。
視圖通常放在一個名為 views.py
的文件中,該文件位于應用程序的文件夾中。
您的 members
文件夾中有一個 views.py
,如下所示:
from django.shortcuts import render
# Create your views here.
找到它并打開它,并將內容替換為:
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello world!")
這是一個關于如何將響應發送回瀏覽器的簡單示例。
但是我們如何執行視圖呢? 好吧,我們必須通過 URL 調用視圖。
在與 views.py
文件相同的文件夾中創建一個名為 urls.py
的文件,并在其中輸入以下代碼:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
剛剛創建的 urls.py
文件是特定于成員應用程序的。我們還必須在根目錄 myworld
中進行一些路由。
在 myworld
文件夾中有一個名為 urls.py
的文件,打開該文件并在 import
語句中添加 include
模塊,并在列表中添加一個 path()
函數。文件將如下所示:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('members/', include('members.urls')),
path('admin/', admin.site.urls),
]
如果服務器未運行,請導航到 /myworld
文件夾并在命令提示符下執行此命令:
$ py manage.py runserver
在瀏覽器窗口的地址欄中輸入 127.0.0.1:8000/members/
在 members
文件夾中創建一個 templates
文件夾,并創建一個名為 myfirst.html
的 HTML
文件。文件結構應該是這樣的:
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
╰┈ templates/
╰┈ myfirst.html
打開 HTML
文件并插入以下內容:
<!DOCTYPE html>
<html>
<body>
<h1>Hello World!</h1>
<p>歡迎來到我的第一個 Django 項目!</p>
</body>
</html>
修改視圖 members/views.py
from django.http import HttpResponse
from django.template import loader
def index(request):
template = loader.get_template('myfirst.html')
return HttpResponse(template.render())
為了能夠處理比“Hello World!”更復雜的東西,我們必須告訴 Django
一個新的應用程序已創建
這是在 myworld
文件夾的 myworld/settings.py
文件中完成的。查找 INSTALLED_APPS[]
列表并添加成員應用程序,如下所示:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'members.apps.MembersConfig'
]
然后運行這個命令:
$ py manage.py migrate
通過導航到 /myworld
文件夾啟動服務器并執行以下命令:
$ py manage.py runserver
在瀏覽器窗口的地址欄中輸入 127.0.0.1:8000/members/
在 /members/
文件夾中,打開 models.py
文件。要在我們的數據庫中添加成員表,首先創建一個成員類,并描述其中的表字段:
from django.db import models
class Members(models.Model):
firstname = models.CharField(max_length=255)
lastname = models.CharField(max_length=255)
然后導航到 /myworld/
文件夾并運行以下命令:
$ py manage.py makemigrations members
# Migrations for 'members':
# members\migrations\0001_initial.py
# - Create model Members
創建一個包含任何新更改的文件并將該文件存儲在 /migrations/
文件夾中。下次運行 py manage.py migrate
時,Django 將根據遷移文件夾中新文件的內容創建并執行一條 SQL 語句。運行遷移命令:
$ py manage.py migrate
從模型創建的 SQL 語句是:
CREATE TABLE "members_members" (
"id" INT NOT NULL PRIMARY KEY AUTOINCREMENT,
"firstname" varchar(255) NOT NULL,
"lastname" varchar(255) NOT NULL
);
<!-- template.html -->
<h1>你好 {{ firstname }},你好嗎?</h1>
在視圖 (views.py
) 中創建變量,上面示例中的變量 firstname
通過視圖發送到模板:
from django.http import HttpResponse
from django.template import loader
def testing(request):
template = loader.get_template('template.html')
context = {
'firstname': '狂徒張三',
}
return HttpResponse(template.render(context, request))
{% with firstname="Tobias" %}
<h1>你好 {{ firstname }},你好嗎?</h1>
<ul>
{% for x in mymembers %}
<li>{{ x.firstname }}</li>
{% endfor %}
</ul>
標簽 | 描述 |
---|---|
autoescape | 指定自動轉義模式是打開還是關閉 |
block | 指定塊部分 |
comment | 指定注釋部分 |
csrf_token | 保護表單免受跨站點請求偽造 |
cycle | 指定要在循環的每個循環中使用的內容 |
debug | 指定調試信息 |
extends | 指定父模板 |
filter | 在返回之前過濾內容 |
firstof | 返回第一個非空變量 |
for | 指定一個 for 循環 |
if | 指定一個 if 語句 |
ifchanged | 僅當自上次迭代以來值已更改時才輸出塊 (用于 for 循環) |
include | 指定包含的內容/模板 |
load | 從另一個庫加載模板標簽 |
lorem | 輸出隨機文本 |
now | 輸出當前日期/時間 |
regroup | 按組對對象進行排序 |
resetcycle | 循環使用,重置循環 |
spaceless | 刪除 HTML 標簽之間的空格 |
templatetag | 輸出指定的模板標簽 |
url | 返回 URL 的絕對 URL 部分 |
verbatim | 指定不應由模板引擎呈現的內容 |
widthratio | 給定值和最大值之間的比率計算寬度值 |
with | 指定要在塊中使用的變量 |
{% if greeting == 1 %}
<h1>Hello</h1>
{% elif greeting == 2 %}
<h1>Welcome</h1>
{% else %}
<h1>Goodbye</h1>
{% endif %}
{% for x in cars %}
<h1>{{ x.brand }}</h1>
<p>{{ x.model }}</p>
<p>{{ x.year }}</p>
{% endfor %}
數據 cars 空的展示內容:
<ul>
{% for x in cars %}
<h1>{{ x.brand }}</h1>
<p>{{ x.model }}</p>
<p>{{ x.year }}</p>
{% empty %}
<li>No members</li>
{% endfor %}
</ul>
forloop.counter
當前循環,從 1 開始forloop.counter0
當前循環,從 0 開始forloop.first
循環是否在其第一次循環中forloop.last
循環是否在其最后一次循環中forloop.parentloop
forloop.revcounter
如果從末尾開始并向后計數,則以 1 結束forloop.revcounter0
如果從末尾開始并向后計數,則以 0 結束<h1>你好 {{ firstname|upper }},你好嗎?</h1>
返回帶有大寫字母的變量名
<h1>歡迎大家{# 較小的注釋 #}</h1>
{% comment %}
<h1>歡迎女士們先生們</h1>
{% endcomment %}
<h1>歡迎大家{# 較小的注釋 #}</h1>
{% comment "這是最初的歡迎信息" %}
<h1>歡迎女士們先生們</h1>
{% endcomment %}
注釋允許您擁有應該被忽略的代碼部分
<h1>你好 {{ firstname|first|upper }},你好嗎?</h1>
返回變量 firstname
的第一個字符,小寫
{% filter upper %}
<h1>Hello everyone, how are you?</h1>
{% endfilter %}
返回內容大寫
如果你想為每次循環使用新的背景顏色,你可以使用 cycle
標簽來做到這一點
<ul>
{% for x in members %}
<li style='background-color:{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' %}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
將參數值保存在變量中,以便以后使用:
<ul>
{% for x in members %}
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
<li style='background-color:{{ bgcolor }}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
你注意到 silent
關鍵字了嗎? 確保添加這個,否則參數值將在輸出中顯示兩次
<ul>
{% for x in members %}
{% cycle 'lightblue' 'pink' 'yellow' 'coral' 'grey' as bgcolor silent %}
{% if forloop.counter == 3 %}
{% resetcycle %}
{% endif %}
<li style='background-color:{{ bgcolor }}'>
{{ x.firstname }}
</li>
{% endfor %}
</ul>
您可以使用 {% resetcycle %}
標簽強制循環重新開始
{% filter upper|linenumbers %}Hello!
my name is
Emil.
What is your name?{% endfilter %}
返回內容大寫
并在每一行添加行號
footer.html
:
<p>您已到達本頁底部,感謝您抽出寶貴時間</p>
template.html
:
<h1>Hello</h1>
<p>此頁面包含模板中的頁腳</p>
{% include 'footer.html' %}
mymenu.html
:
<div>HOME | {{ me }} | ABOUT | FORUM | {{ sponsor }}</div>
template.html
:
{% include mymenu.html with me="張三" sponsor="Reference" %}
<h1>Welcome</h1>
<p>This is my webpage</p>
Keyword | 描述 |
---|---|
add | 添加指定的值 |
addslashes | 在任何引號字符之前添加一個斜杠,以轉義字符串 |
capfirst | 返回大寫的第一個字母 |
center | 使值在指定寬度的中間居中 |
cut | 刪除任何指定的字符或短語 |
date | 以指定格式返回日期 |
default | 如果值為 False ,則返回指定值 |
default_if_none | 如果值為 None ,則返回指定的值 |
dictsort | 按給定值對字典進行排序 |
dictsortreversed | 按給定值對字典進行反向排序 |
divisibleby | 如果該值可以除以指定的數字,則返回 True ,否則返回 False |
escape | 從字符串中轉義 HTML 代碼 |
escapejs | 從字符串中轉義 JavaScript 代碼 |
filesizeformat | 將數字返回為文件大小格式 |
first | 返回對象的第一項(對于字符串,返回第一個字符) |
floatformat | 將浮點數四舍五入到指定的小數位數,默認為一位小數 |
force_escape | 從字符串中轉義 HTML 代碼 |
get_digit | 返回數字的特定數字 |
iriencode | 將 IRI 轉換為 URL 友好字符串 |
join | 將列表中的項目返回為字符串 |
json_script | 將一個對象返回為由 <script></script> 標簽包圍的 JSON 對象 |
last | 返回對象的最后一項(對于字符串,返回最后一個字符) |
length | 返回對象中的項目數,或字符串中的字符數 |
length_is | 如果長度與指定的數字相同,則返回 True |
linebreaks | 返回帶有 <br> 而不是換行符和 <p> 而不是多個換行符的文本 |
linebreaksbr | 返回帶有 <br> 的文本,而不是換行符 |
linenumbers | 返回每行帶有行號的文本 |
ljust | 根據指定的寬度左對齊值 |
lower | 以小寫字母返回文本 |
make_list | 將值轉換為列表對象 |
phone2numeric | 將帶字母的電話號碼轉換為數字電話號碼 |
pluralize | 如果指定的數值不是 1 ,則在值的末尾添加一個 s |
pprint | |
random | 返回對象的隨機項 |
rjust | 根據指定的寬度右對齊值 |
safe | 標記此文本是安全的,不應進行 HTML 轉義 |
safeseq | 將對象的每個項目標記為安全且項目不應進行 HTML 轉義 |
slice | 返回文本或對象的指定切片 |
slugify | 將文本轉換為一個長字母數字小寫單詞 |
stringformat | 將值轉換為指定格式 |
striptags | 從文本中刪除 HTML 標記 |
time | 以指定格式返回時間 |
timesince | 返回兩個日期時間之間的差 |
timeuntil | 返回兩個日期時間之間的差 |
title | 文本中每個單詞的第一個字符大寫,所有其他字符都轉換為小寫 |
truncatechars | 將字符串縮短為指定數量的字符 |
truncatechars_html | 將字符串縮短為指定數量的字符,而不考慮任何 HTML 標記的長度 |
truncatewords | 將字符串縮短為指定數量的單詞 |
truncatewords_html | 將字符串縮短為指定數量的單詞,而不考慮任何 HTML 標記 |
unordered_list | 將對象的項目返回為無序列的 HTML 列表 |
upper | 以大寫字母返回文本 |
urlencode | URL 對字符串進行編碼 |
urlize | 將字符串中的任何 URL 作為 HTML 鏈接返回 |
urlizetrunc | 將字符串中的任何 URL 作為 HTML 鏈接返回,但會將鏈接縮短為指定的字符數 |
wordcount | 返回文本中的單詞數 |
wordwrap | 以指定的字符數換行 |
yesno | 將布爾值轉換為指定值 |
i18n | |
l10n | |
tz |
Keyword | 描述 |
---|---|
contains | 包含短語 |
icontains | 與包含相同,但不區分大小寫 |
date | 匹配日期 |
day | 匹配日期(日期,1-31)(日期) |
endswith | 以。。結束 |
iendswith | 與 endwidth 相同,但不區分大小寫 |
exact | 完全匹配 |
iexact | 與精確相同,但不區分大小寫 |
in | 匹配其中一個值 |
isnull | 匹配 NULL 值 |
gt | 比...更棒 |
gte | 大于或等于 |
hour | 匹配一個小時(對于日期時間) |
lt | 少于 |
lte | 小于或等于 |
minute | 匹配一分鐘(對于日期時間) |
month | 匹配一個月(日期) |
quarter | 匹配一年中的一個季度 (1-4)(用于日期) |
range | 之間的匹配 |
regex | 匹配正則表達式 |
iregex | 與正則表達式相同,但不區分大小寫 |
second | 匹配一秒(對于日期時間) |
startswith | 以 ... 開始 |
istartswith | 與 startswith 相同,但不區分大小寫 |
time | 匹配時間(用于日期時間) |
week | 匹配周數 (1-53 )(用于日期) |
week_day | 匹配一周中的某一天 (1-7) 1 是星期日 |
iso_week_day | 匹配 ISO 8601 星期幾 (1-7) 1 是星期一 |
year | 匹配一年(日期) |
iso_year | 匹配 ISO 8601 年份(日期) |
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ myfirst.css
打開 CSS
文件 (members/static/myfirst.css
) 并插入以下內容:
body {
background-color: lightblue;
font-family: verdana;
}
修改模板 (members/templates/template.html
) 引入 css 文件
{% load static %}
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="{% static 'myfirst.css' %}">
<body>
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ myfirst.js
打開 JS
文件 (members/static/myfirst.js
) 并插入以下內容:
function myFunction() {
alert("Hello from a static file!");
}
修改模板 (members/templates/template.html
) 引入 JS
文件
{% load static %}
<!DOCTYPE html>
<html>
<script src="{% static 'myfirst.js' %}"></script>
<body>
<button onclick="myFunction()">Click me!</button>
myworld
├┈ manage.py
├┈ myworld/
╰┈ members/
├┈ templates/
├┈ static/
╰┈ pineapple.jpg
打開 JS
文件 (members/static/pineapple.jpg
) 并插入以下內容:
function myFunction() {
alert("Hello from a static file!");
}
修改模板 (members/templates/template.html
) 引入 jpg
文件
{% load static %}
<!DOCTYPE html>
<html>
<body>
<img src="{% static 'pineapple.jpg' %}">
</body>
</html>