課程地址:
慕課網(wǎng)免費視頻三小時帶你入門Django框架
一浦译、環(huán)境搭建
1.1 環(huán)境準備
- python環(huán)境安裝:
使用python版本:3.5+
- 方案1:原生python環(huán)境
- 方案2:科學(xué)結(jié)算Anaconda Python環(huán)境(推薦)
減少Python第三方庫的困擾荡澎,全身心投入到業(yè)務(wù)開發(fā)當(dāng)中
- IDE工具安裝:
- pycharm
說明:該文章基于mac系統(tǒng),windows和linux類似
1.2 安裝andconda
- 到官網(wǎng)下載Andconda
- 添加anaconda環(huán)境變量到zsh
1. vim .zshrc
2. add system path
# andconda
export PATH=/opt/anaconda3/bin:$PATH
3. source .zshrc
- 終端輸入 conda,顯示以下界面說明配置成功
2.3 安裝django 2.0
- 命令行安裝(使用豆瓣源,下載更快)
pip install -i https://pypi.douban.com/simple/ django==2.0
- 終端輸入django-admin狰晚,顯示以下界面說明安裝成功
2.4. pycharm安裝
訪問官網(wǎng)pycharm進行下載,點擊安裝即可
二缴啡、Django項目初體驗
2.1 初識Django項目
2.1.1 Django的基本命令
- startproject 創(chuàng)建一個Django項目
- startapp 創(chuàng)建一個Django應(yīng)用
- check 檢查項目完整性
- runserver 本地簡易運行Django項目
- shell 進入Django項目的Python Shell環(huán)境
- test 執(zhí)行Django測試用例
2.1.2 Django的基本指令(數(shù)據(jù)庫相關(guān))
- makemigrations 創(chuàng)建模型變更的遷移文件壁晒,生成數(shù)據(jù)庫DDL語句
- migrate 執(zhí)行上一個命令創(chuàng)建的遷移文件,執(zhí)行DDL語句
- dumpdata 把數(shù)據(jù)庫數(shù)據(jù)導(dǎo)出到文件
- loaddata 把文件數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫
2.1.3 創(chuàng)建一個項目
- 創(chuàng)建一個項目
cd code/python # 1. 自己創(chuàng)建的python項目目錄
django-admin startproject django_introduction # 2. 創(chuàng)建Django項目指令
- 添加代碼到gitee倉庫
- 使用pycharm打開django_introduction目錄
- 配置django_introduction的python環(huán)境
2.2 初識Django應(yīng)用
2.2.1 Django應(yīng)用 VS Django項目
- 一個Django項目就是一個基于Django的Web應(yīng)用
- 一個Django應(yīng)用就是一個可重用的Python軟件包
- 每個應(yīng)用可以自己管理模型业栅、視圖秒咐、模板、路由和靜態(tài)文件等
- 一個Djagon項目包含一組配置和若干個Django應(yīng)用
2.2.2 Django應(yīng)用目錄介紹
- 使用pycharm安裝django
問題:conda命令行進入安裝的django不在該環(huán)境
解決:臨時使用pycharm安裝
- 創(chuàng)建應(yīng)用blog碘裕,打開terminal携取,輸入 python manage.py startapp blog
- 查看blog目錄
2.3. Django HelloWorld
2.3.1 Django視圖(What、Why&How)
- 沒有框架的時代:hello.html
- 不可能通過HTML表達網(wǎng)頁所有的內(nèi)容
- Django視圖產(chǎn)生內(nèi)容
2.3.2 Django路由(What帮孔、What&How)
- runserver 可以看到Django歡迎頁面
- 請求沒辦法到達剛才的視圖函數(shù)
- 需要配置路由雷滋,綁定視圖函數(shù)和URL
2.3.3 代碼編寫
- 應(yīng)用編輯視圖blog/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def hello_world(request):
return HttpResponse("Hello World")
- 應(yīng)用編輯路由blog/urls.py
from django.urls import path
import blog.views
urlpatterns = [
path("hello_world", blog.views.hello_world)
]
- 項目編輯路由django_introduction/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')) # add this line
]
- 項目安裝應(yīng)用django_introduction/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# myapp blog
'blog.apps.BlogConfig' # add this line
]
- 點擊IDE的運行按鈕
- 訪問http://127.0.0.1:8000/blog/hello_world
- 整個訪問流程圖如下
三、Django模型層
3.1 模型層簡介
3.1.1 模型層是什么
- 位于Django視圖層和數(shù)據(jù)庫之間
- Python對象和數(shù)據(jù)庫表之間轉(zhuǎn)換
3.1.2 為什么需要模型層
- 屏蔽不同數(shù)據(jù)庫之間的差異
- 開發(fā)者更加專注于業(yè)務(wù)邏輯的開發(fā)
- 提供很多便捷工具有助開發(fā)
3.1.3 模型層的相關(guān)配置
數(shù)據(jù)庫默認配置在項目settings.py文件文兢,sqlite3數(shù)據(jù)庫
3.2 創(chuàng)建博客文章模型
3.2.1 設(shè)計博客模型
- 文章標題 文本類型
- 文章摘要 文本類型
- 文章內(nèi)容 文本類型
- 唯一ID標記 Int數(shù)字類型(自增晤斩、主鍵)
- 發(fā)布日期 日期類型
3.2.2 模型層定義字段
- 定義類型
- 數(shù)字類型 IntegerField
- 文本類型 TextField
- 日期類型 DateTimeField
- 自增ID AutoField
- 主鍵定義 primary_key屬性
- 應(yīng)用創(chuàng)建model blog/models.py
class Article(models.Model):
# 文章唯一ID
article_id = models.AutoField(primary_key=True)
# 文章標題(注意TextFiled有括號)
title = models.TextField()
# 文章摘要
brief_content = models.TextField()
# 文章內(nèi)容
content = models.TextField()
# 文章發(fā)布時間
publish_date = models.DateTimeField(auto_now=True)
- 終端運行指令創(chuàng)建Article model
說明:
makemigrations生成ddl(數(shù)據(jù)庫模式定義語言)
migrate真正地去執(zhí)行ddl
3.3 初識Django Shell
3.3.1 Django Shell是什么
- Python Shell,用于交互式的Python編程
- Django Shell也類似姆坚,集成Django項目環(huán)境
3.3.2 為什么需要Django Shell
- 臨時性操作使用Django Shell更加方便
- 小范圍Debug更簡單澳泵,不需要運行整個項目來測試
方便開發(fā)、方便測試兼呵、方便Debug
3.3.3 Django Shell的使用
實例:創(chuàng)建一遍文章
3.4. 初識Django Admin模塊
4.1 Django Admin模塊是什么
- Django的后臺管理工具
- 讀取定義的模型元數(shù)據(jù)兔辅,提供強大的管理使用頁面
4.2 為什么需要Django Admin模塊
- Django Shell新增文章太復(fù)雜了
- 管理頁面是基礎(chǔ)設(shè)施中重要的部分
- 認證用戶腊敲、顯示管理模型、校驗輸入等功能類似
4.3 Django Admin模塊的使用
- 創(chuàng)建管理員用戶
- 登錄頁面進行管理
- 啟動項目维苔,訪問網(wǎng)址 http://127.0.0.1:8000/admin
- 輸入步驟1創(chuàng)建的管理員賬號密碼
- 可以發(fā)現(xiàn)沒有我們自定義的Article -> 應(yīng)用admin.py注冊Article
from django.contrib import admin
# Register your models here.
from .models import Article
admin.site.register(Article)
- 發(fā)現(xiàn)Article顯示的標題不友好“Article object”碰辅,應(yīng)用models.py 新增str方法,重啟服務(wù)器
3.5 實現(xiàn)博客數(shù)據(jù)返回頁面
5.1 blog/views.py添加響應(yīng)
from blog.models import Article
def article_content(request):
article = Article.objects.all()[0]
title = article.title
brief_content = article.brief_content
content = article.content
article_id = article.article_id
publish_date = article.publish_date
return_str = 'title:%s,brief_content:%s,content:%s,article_id:%s,publish_date:%s' % (
title, brief_content, content, article_id, publish_date)
return HttpResponse(return_str)
5.2 blog/urls.py配置路由
urlpatterns = [
path("hello_world", blog.views.hello_world),
path("content", blog.views.article_content) // add this line
]
訪問內(nèi)容地址:http://127.0.0.1:8000/blog/content
四介时、Django視圖與模板
4.1 使用Bootstrap實現(xiàn)靜態(tài)博客頁面
4.1.1 頁面布局設(shè)計
- 博客首頁
- 文章詳情頁
4.1.2 Bootstrap以及Bootstrap的柵格系統(tǒng)
- 來自美國Twitter的前端框架
- 提供非常多的控件并附帶源碼
- 柵格系統(tǒng)把頁面均分為12等份
- 官方網(wǎng)站:https://www.bootcss.com/
- bootstrap使用:https://v3.bootcss.com/getting-started/
4.1.3 實現(xiàn)靜態(tài)頁面
- 文章標題 blog新建templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三小時入門Django Web框架</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
<h1>三小時入門Django Web框架
<small>-by ybxiang</small></h1>
</div>
<div class="container page-body">
<div class="col-md-9" role="main">
<div class="body-main">
<div>
<h2>文章標題1</h2>
<p>
目標是設(shè)定一個定性的時間內(nèi)目標(通常是一個季度)乎赴。關(guān)鍵的結(jié)果是由量化指標形式呈現(xiàn)的,用來衡量在這段時間結(jié)束時是否達到了目標潮尝。 [6]
在全面展開工作時,OKR就存在于公司(頂級愿景)饿序、團隊(被繼承并由團隊生成勉失,而不僅僅是個人目標的一部分)和個人層面(個人發(fā)展和個人貢獻)上了。
大多數(shù)目標通常是由管理層定義的原探,但有些目標是自下而上的乱凿,而不是為了增加團隊的積極性。 [7]
公司發(fā)布的OKR演示文稿或包含問答的陳述咽弦、報告徒蟆,可以確保在最終完成之前對依賴關(guān)系進行跨功能的對齊和協(xié)議。
在目標時期結(jié)束時型型,要特別注意對每個目標的每個關(guān)鍵結(jié)果進行評估段审。不同的人對有目標的期望是不同的。谷歌和Uber建議每個季度員工應(yīng)該實現(xiàn)約70%的“OKR”闹蒜,這是每個季度的關(guān)鍵業(yè)績數(shù)據(jù)寺枉,而Zynga則希望員工每季度能實現(xiàn)2至3個“OKR”。
[8]
</p>
</div>
</div>
</div>
<div class="col-md-3" role="complementary">
<div>
<h2>最新文章</h2>
<h4><a href="#">最新文章1</a></h4>
<h4><a href="#">最新文章2</a></h4>
<h4><a href="#">最新文章3</a></h4>
<h4><a href="#">最新文章4</a></h4>
<h4><a href="#">最新文章5</a></h4>
<h4><a href="#">最新文章6</a></h4>
<h4><a href="#">最新文章7</a></h4>
<h4><a href="#">最新文章8</a></h4>
<h4><a href="#">最新文章9</a></h4>
</div>
</div>
</div>
</body>
</html>
- 瀏覽器打開html預(yù)覽效果
- 文章詳情 blog新建templates/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三小時入門Django Web框架</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
<h1>文章標題1</h1>
</div>
<div class="container body-main">
<p>
目標是設(shè)定一個定性的時間內(nèi)目標(通常是一個季度)绷落。關(guān)鍵的結(jié)果是由量化指標形式呈現(xiàn)的姥闪,用來衡量在這段時間結(jié)束時是否達到了目標。 [6]
在全面展開工作時砌烁,OKR就存在于公司(頂級愿景)筐喳、團隊(被繼承并由團隊生成,而不僅僅是個人目標的一部分)和個人層面(個人發(fā)展和個人貢獻)上了函喉。
大多數(shù)目標通常是由管理層定義的避归,但有些目標是自下而上的,而不是為了增加團隊的積極性函似。 [7]
公司發(fā)布的OKR演示文稿或包含問答的陳述槐脏、報告,可以確保在最終完成之前對依賴關(guān)系進行跨功能的對齊和協(xié)議撇寞。
在目標時期結(jié)束時顿天,要特別注意對每個目標的每個關(guān)鍵結(jié)果進行評估堂氯。不同的人對有目標的期望是不同的。谷歌和Uber建議每個季度員工應(yīng)該實現(xiàn)約70%的“OKR”牌废,這是每個季度的關(guān)鍵業(yè)績數(shù)據(jù)咽白,而Zynga則希望員工每季度能實現(xiàn)2至3個“OKR”。
[8]
</p>
</div>
</div>
</body>
</body>
</html>
4.2 初識Django的模板系統(tǒng)
4.2.1 模板系統(tǒng)簡介
- 視圖文件不適合編碼HTML
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
- 頁面設(shè)計改變需要修改Python代碼
- 網(wǎng)頁邏輯和網(wǎng)頁視圖應(yīng)該分開設(shè)計
- 模板系統(tǒng)的表現(xiàn)形式是文本
- 分離文檔的表現(xiàn)形式和變現(xiàn)內(nèi)容
- 模板系統(tǒng)定義了特有的標簽占位符
4.2.2 基本語法
- 變量標簽:{{ 變量 }}
<html><body>{{ now }}</body></html>
- for循環(huán)標簽:{% for x in list %}, {% endfor%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
- if-else分支標簽:{% if %}鸟缕,{% else %}晶框,{% endif %}
{% if true %}
<p>it is a true part.</p>
{% else %}
<p>it is a false part.</p>
{% endif %}
4.3 使用模板系統(tǒng)渲染博客頁面
4.3.1 博客首頁
- index.html移動到blog/templates/blog/index.html,讀取內(nèi)容
<div class="container page-body">
<div class="col-md-9" role="main">
<div class="body-main">
{% for article in article_list %}
<div>
<h2>{{ article.title }}</h2>
<p>
{{ article.brief_content }}
</p>
</div>
{% endfor %}
</div>
</div>
<div class="col-md-3" role="complementary">
<div>
<h2>最新文章</h2>
{% for article in article_list %}
<h4><a href="#">{{ article.title }}</a></h4>
{% endfor %}
</div>
</div>
</div>
- views.py放內(nèi)容
def get_index_page(request):
all_article = Article.objects.all()
return render(request, 'blog/index.html', {
'article_list': all_article
})
- urls.py配置路由
path("index", blog.views.get_index_page)
4.3.2 文章詳情頁
- detail.html移動到blog/templates/blog/deatail.html懂从,讀取內(nèi)容
<body>
<div class="container page-header">
<h1>{{ curr_article.title }}</h1>
</div>
<div class="container body-main">
<p>
{% for section in section_list %}
<p>{{ section }}</p>
{% endfor %}
</p>
</div>
</body>
- views.py放內(nèi)容
def get_detail_page(request):
curr_article = Article.objects.all()[0]
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list
})
- urls.py配置路由
path("detail", blog.views.get_detail_page)
4.4 實現(xiàn)文章詳情頁面跳轉(zhuǎn)
當(dāng)前問題:
- 不支持博客首頁到文章詳情頁的跳轉(zhuǎn)
- 只能打開某一遍文章的詳情頁
當(dāng)前方案:
- 設(shè)計文章詳情頁URL -> 完善視圖函數(shù)邏輯 -> 實現(xiàn)首頁跳轉(zhuǎn)
4.4.1 設(shè)計文章詳情頁URL
/blog/detail => 不能指定某一篇博客
- /blog/detail/1 => 博客唯一ID為1的文章
- /blog/detail/2 => 博客唯一ID未2的文章
4.4.2 完善視圖函數(shù)邏輯
URL路徑參數(shù)的獲取和傳遞
- urls.py 配置路由
path("detail/<int:article_id>", blog.views.get_detail_page)
- views.py 設(shè)置數(shù)據(jù)
def get_detail_page(request, article_id):
all_article = Article.objects.all()
curr_article = None
for article in all_article:
if article.article_id == article_id:
curr_article = article
break
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list
})
- index.html 修改跳轉(zhuǎn)邏輯
- 訪問http://127.0.0.1:8000/blog/index 點擊文章標題授段,跳轉(zhuǎn)到文章詳情頁
4.5 實現(xiàn)上下篇文章跳轉(zhuǎn)
4.5.1 代碼實現(xiàn)
- detail.html新增上下頁組件
<body>
<div class="container page-header">
<h1>{{ curr_article.title }}</h1>
</div>
<div class="container body-main">
<p>
{% for section in section_list %}
<p>{{ section }}</p>
{% endfor %}
</p>
</div>
<div>
<nav aria-label="...">
<ul class="pager">
<li><a href="/blog/detail/{{ previous_article.article_id }}">上一篇:{{ previous_article.title }}</a></li>
<li><a href="/blog/detail/{{ next_article.article_id }}">下一篇:{{ next_article.title }}</a></li>
</ul>
</nav>
</div>
</body>
- views.py設(shè)置上下頁數(shù)據(jù)
def get_detail_page(request, article_id):
all_article = Article.objects.all()
curr_article = None
previous_article = None
next_article = None
for index, article in enumerate(all_article):
if article.article_id == article_id:
curr_article = article
if index >= 1:
previous_index = index - 1
else:
previous_index = 0
if index < len(all_article) - 1:
next_index = index + 1
else:
next_index = index
previous_article = all_article[previous_index]
next_article = all_article[next_index]
break
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list,
'previous_article': previous_article,
'next_article': next_article
})
4.6 實現(xiàn)分頁功能
4.6.1 實現(xiàn)分頁功能流程
- Bootstrap實現(xiàn)分頁按鈕 -> 設(shè)計分頁URL -> 使用Django分頁組件實現(xiàn)分頁功能
4.6.2 index.html 拷貝分頁組件
4.6.3實現(xiàn)分頁標識設(shè)計
- /blog/detail/1 => 博客唯一ID為1的文章
- /blog/index?page = 1 => 分頁為1的首頁
4.6.4 views.py設(shè)置分頁數(shù)據(jù)
- 使用python shell進行分頁功能測試
- 登錄admin管理后臺添加幾條article,方便測試分頁
- index.html設(shè)置UI
- views.py設(shè)置數(shù)據(jù)(倒敘字段簽名加【-】)