目錄
0、視頻鏈接
?1、環境配置
?2、django基本命令
1)常見命令
?2)數據庫相關的Django命令
?3、Django項目
1)Django創建項目
?2)項目目錄介紹
3)運行初始化的Django項目
?4、Django應用
1)Django項目和Django應用
?2)Django應用目錄
(1)創建Django應用
(2)應用目錄各文件介紹
?問題1:視圖、路由、模型是什么意思?
5、Django視圖&Django路由(what、why、how)
1)Django視圖(view.py)——創建邏輯函數(數據處理)
?2)Django路由(url.py)——創建URL和函數的映射關系
①路由表和路由
②Django路由表的創建——path
③二級路由——項目路由容器轉派到各應用路由容器中
3)request對象和response對象
①request對象——接收客戶端返回的請求數據
② Response對象——根據客戶端的請求在服務端獲得的數據處理后要返回給客戶端的數據(響應)
4)一個簡單的Django項目(含視圖及路由文件修改)——helloworld
?①應用視圖函數編寫——獲得網頁請求,返回“helloworld”
②配置應用層面的路由——獲得路由名后,到view.py查找對應的邏輯函數
③配置項目層面的路由——獲得URL后,根據路由將截斷的URL分配到對應的應用路由表中urls.py
④將APP應用配置到項目中
?⑥本項目流程
?問題2:什么是Django模型層?
6、Django模型層(models.py)
1)模型層簡介(概念和作用)
?2)Django中模型層的配置(settings.py)
7、Django模型的創建——創建博客文章類型(models.py)
1)明確博客文章的組成字段及其類型
2)定義字段
?3)文章模型的定義
4)python manage.py makemigrations生成遷移文件
5)python manage.py migrate 遷移模型到數據庫
8、Django shell——交互式環境
1)what&why
?2)how——向數據庫中插入一條記錄
?
?
9、Django admin模塊——管理員功能(用于后臺修改數據)
1)what&why
?2)how——如何使用admin模塊
①創建管理員身份
②運行admin模塊
③在admin.py中注冊模型
?10、從數據庫中獲取數據并且返回給瀏覽器
1)編寫代碼
?2)整個過程的流程圖
?
?問題3:什么是Django模板(template)
11、django 模板系統
1)模板系統簡介
?2)簡單的模板例子
3)Django模板系統的基本語法
12、boostrap以及boostrap柵格系統
13、【實操】利用boostrap和Django模板實現博客系統
1)博客頁面設計(博客首頁+博客文章詳情頁)
2)博客首頁設計
①書寫博客首頁的模板(HTML)
?②修改視圖文件函數返回模板變量值
?③設置路由
④python manage.py runserver運行
3)博客文章詳情頁設計
①書寫博客首頁的模板(HTML)
??②修改視圖文件函數返回模板變量值
?③設置路由?
④python manage.py runserver運行?
4)實現博客首頁跳轉至文章詳情頁
①文章詳情頁URL鏈接設計
②修改詳情頁鏈接路由設置
③修改視圖函數get_detail_page
④為博客首頁的文章列表添加鏈接
5)實現上下篇文章跳轉
?①設計翻頁按鈕——boostrap翻頁組件
?②給每一個詳情頁的上下篇文章按鈕設置鏈接
③修改視圖函數
?6)實現博客首頁分頁功能
〇Django分頁組件工具——Django.core.paginator.Paginator
①設計分頁按鈕——boostrap分頁組件
?②設計分頁的URL
③修改視圖函數
④修改index.html模板
?7)實現最新文章的顯示功能
14、總結
15、問題遺留
1)如何將網頁上用戶輸入的信息保存到數據庫
2)除了boostrap前端框架是否還有其他前端框架
3)實現一個網頁版管理系統
0、視頻鏈接
視頻鏈接:
三小時帶你入門Django框架_嗶哩嗶哩_bilibiliDjango框架是Python語言最熱門的Web框架之一。本課程將帶你學習Django的項目結構,路由配置,和admin模塊等知識點,并且將理論與實踐結合,利用Django框架高效便捷,容易上手的特性。帶你三小時搭建一個網站,讓你快速上手Web開發。如果你有簡單的Python語法基礎,并且渴望項目實踐,那么這門課程你不容錯過。海量優質原創課程盡在【慕課網】www.imooc.com還請觀眾老爺https://www.bilibili.com/video/BV1Sf4y1v77f?p=1
?
?1、環境配置
Python3.5+
pycharm IDE
Django2.0
安裝Django: pip install django==2.0
?測試Django是否安裝成功:
終端輸入:django-admin
出現下面的圖示,不報錯即可
?
?2、django基本命令
1)常見命令
[django]
??? check:校驗項目的完整性
??? compilemessages
??? createcachetable
??? dbshell
??? diffsettings
??? dumpdata
??? flush
??? inspectdb
??? loaddata
??? makemessages
??? makemigrations
??? migrate
??? runserver:進入Django的環境,并且運行Django的項目
??? sendtestemail
??? shell:進入Django shell的環境
??? showmigrations
??? sqlflush
??? sqlmigrate
??? sqlsequencereset
??? squashmigrations
??? startapp:啟動Django應用
??? startproject:啟動Django項目
??? test:執行用例
??? testserver
?
?
?2)數據庫相關的Django命令
?
?
?3、Django項目
1)Django創建項目
?
django-admin startproject 項目名稱
django-admin startproject blogWebSystem
創建成功后項目如下所示:
??
?2)項目目錄介紹
參考:1、Django框架目錄介紹 - 我是旺旺 - 博客園https://www.cnblogs.com/licl11092/p/7595726.html
?
?
?
3)運行初始化的Django項目
python manage.py runserver
?
?復制鏈接到網頁上打開,出現下面的界面表示創建項目成功
?
?4、Django應用
1)Django項目和Django應用
?
??
??
?2)Django應用目錄
(1)創建Django應用
Django manager.py startapp 應用名稱
Django manager.py startapp blog
??
(2)應用目錄各文件介紹
??
??
?問題1:視圖、路由、模型是什么意思?
5、Django視圖&Django路由(what、why、how)
1)Django視圖(view.py)——創建邏輯函數(數據處理)
博客《Django中的視圖(view) - rain、 - 博客園》中對視圖的解釋:
視圖就是Django項目下的view.py文件,它的內部是一系列的函數或者是類,用來專門處理客戶端訪問請求后處理請求并且返回相應的數據,相當于一個中央情報處理系統
?
視圖的作用(總結為兩點):
①將網頁端(客戶端)的請求接收,然后將請求反饋給服務端(服務器、本機);
②將服務端的數據返回給網頁端(客戶端),并且顯示在網頁上。
其實就是一個中央數據處理站,服務端和客戶端的樞紐
?2)Django路由(url.py)——創建URL和函數的映射關系
①路由表和路由
博客《django路由介紹_越前浩波的博客-CSDN博客_django路由》中對路由的介紹
簡單來說,路由就是URL到函數的映射。
??????? route就是一條路由,它將一個URL路徑和一個函數進行映射,例如:
/users -> getAllUsers() /users/count -> getUsersCount()
? ? ? ? 這就是兩條路由,當訪問 /users 的時候,會執行 getAllUsers() 函數;當訪問 /users/count 的時候,會執行 getUsersCount() 函數。
??????? router 可以理解為一個容器,或者說一種機制,它管理了一組 route。
??????? 簡單來說,route 只是進行了URL和函數的映射,而在當接收到一個URL之后,去路由映射表中查找相應的函數,這個過程是由 router 來處理的。路由系統的工作總結起來就是:制定路由規則,分析url,分發請求到響應視圖函數中。
路由系統的路由功能基于路由表,路由表是預先定義好的url和視圖函數的映射記錄,換句話說,可以理解成將url和視圖函數做了綁定,映射關系有點類似一個python字典:
url_to_view_dic = {'路徑1': view_func_1,'路徑2': view_func_2,'路徑n': view_func_n,... }
路由表的建立是控制層面,需要在實際業務啟動前就準備完畢,即:先有路由,后有業務。
一旦路由準備完畢,業務的轉發將會完全遵從路由表的指導:去往路徑1的request --> 被路由器分發到view_func_1函數處理 去往路徑2的request --> 被路由器分發到view_func_2函數處理 去往路徑n的request --> 被路由器分發到view_func_n函數處理 ...
②Django路由表的創建——path
django框架中的工具:path
所有的web請求都將以django項目目錄下的urls.py文件作為路由分發主入口,所以如果要完成最簡單的路由功能,只需要在此文件中預先配置好路由表即可。path是django v2的工具。
# 項目urls.py文件, 目前兩種工具可以任選使用
re_path(r'home/', views.index)
path('articles/<int:id>', views.show_article)
路由表示例:
# urls.py文件urlpatterns = [# 自帶后臺管理頁面路由path('admin/', admin.site.urls),# 新增path('add/author/$', views.add_author),path('add/book/$', views.add_book),# 刪除path('delete/author/(\d+)', views.delete_author),path('delete/book/(\d+)', views.delete_book),# 修改path('edit/author/(\d+)', views.edit_author),path(r'edit/book/(\d+)', views.edit_book),
]
注:在Django中分為兩種路由,一種是應用層面的路由,一種是Django項目層面的路由
③二級路由——項目路由容器轉派到各應用路由容器中
Django 二級路由工具:include
二級路由的意思就是把項目urls文件中的路由整理劃分,分布到各自的應用目錄urls文件中
- 1、降低項目urls路由文件中路由數量,由各自應用urls路由文件承擔
- 2、解耦整個項目的路由表,出現路由問題的時候可以單獨在二級路由表中處理
- 3、多級路由以樹形結構執行查詢,在路由數量很大的時候,可以比單路由表有更快的查詢速度
re_path(r'game/', include('game_app.urls')),
re_path(r'chat/', include('chat_app.urls')),
re_path(r'vidio/', include('vidio_app,urls'),
用include實現二級路由表,二級路由會將在一級路由匹配到的url截斷后再發送給子路由表繼續匹配。以如下一級路由表為例,如果服務器收到一個http://www.xxx.com:8080/game/user/add/?name=a&pswd=b的請求,首先會匹配一級路由表中的game/并將截斷后的user/add/發送到二級路由表繼續匹配。
如上所述,先獲得game/,截斷后的user/add/發送到game_app.urls路由表中進行下一步的路由表進行匹配
3)request對象和response對象
①request對象——接收客戶端返回的請求數據
當一個頁面數據被請求時,Django就會將請求的所有數據自動傳遞給約定俗稱的request這個參數,而我們只需要拿到這個參數并對其進行一系列的操作即可獲得所有與操作有關的數據
操作request對象的相應方法
- path_info???? 返回用戶訪問url,不包括域名
- method????????請求中使用的HTTP方法的字符串表示,全大寫表示。
- GET??????????????包含所有HTTP ?GET參數的類字典對象
- POST???????????包含所有HTTP POST參數的類字典對象
- body????????????請求體,byte類型 request.POST的數據就是從body里面提取到的
② Response對象——根據客戶端的請求在服務端獲得的數據處理后要返回給客戶端的數據(響應)
與由Django自動創建的HttpRequest對象相比,HttpResponse對象是我們的職責范圍了。我們寫的每個視圖都需要實例化,填充和返回一個HttpResponse。
HttpResponse類位于django.http模塊中。
4)一個簡單的Django項目(含視圖及路由文件修改)——helloworld
要做的事情其實就是打開Django項目后,在鏈接上增加/user后,能夠通過視圖函數得到響應值“helloworld”,并且顯示在html中
流程:
- 輸入URL
- 將URL傳遞給項目的urls.py
- 根據URL的一級路由和項目的urls.py中的映射表將URL分配到對應的應用的urls.py文件
- 根據URL的二級路由和應用的urls.py中的映射表將URL分配到下一級應用的urls.py文件
- ...
- 最后根據最后一級應用的urls.py文件的映射表調用view.py中的函數
- view.py中的函數接收由上述步驟得到的請求參數request,獲得響應數據reponse
- 然后將Reponse響應數據返回到瀏覽器中
?①應用視圖函數編寫——獲得網頁請求,返回“helloworld”
打開應用目錄下的view.py文件,修改如下:
from django.shortcuts import renderfrom django.http import HttpResponse# Create your views here.def hello_world(request):# 這里不能直接返回字符串,而是需要將字符串傳入到HttpResponse類中,實例化響應類后進行返回return HttpResponse("hello world")
其中request是客戶端請求回來的參數對象,Reponse是服務端返回的響應對象
②配置應用層面的路由——獲得路由名后,到view.py查找對應的邏輯函數
在應用里面新建一個urls.py文件,作為路由配置文件的編寫
from django.urls import path
from views import hello_worldurlpatterns = [# 當指派到本應用的路由一級路由名為hello_world時,調用view.py中的hello_world函數path('hello_world',hello_world)
]
③配置項目層面的路由——獲得URL后,根據路由將截斷的URL分配到對應的應用路由表中urls.py
打開項目的urls.py文件
from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),# 將URL分配到對應的APP當中進行二級路由,這里是將其分配到blob.urls中path("user/",include("blob.urls"))
]
④將APP應用配置到項目中
打開項目的settings.py文件
?
其中blog.apps.BlogConfig是在創建APP的時候生成的,可以查看應用層的apps.py文件
⑤運行項目——python manage.py runserver
修改鏈接最后運行得到下圖結果
?
?⑥本項目流程
?
?問題2:什么是Django模型層?
6、Django模型層(models.py)
模型層其實就是Python類,主要的作用是與數據庫進行數據交互,在數據庫和視圖之間,類似于DAO(data access object)的作用。
注:創建一個模型,其實就是根據網頁的元素設計一張數據表,確定數據表的字段、字段類型、主鍵等參數
1)模型層簡介(概念和作用)
?
?
?2)Django中模型層的配置(settings.py)
setting.py文件——DATABASES字典
?
具體Django模型數據庫配置可見:
Settings | Django documentation | Django
https://docs.djangoproject.com/en/2.0/ref/settings/#databases支持的驅動有:
?
?配置mysql數據庫(將下面的postgresql改成mysql即可):
?
7、Django模型的創建——創建博客文章類型(models.py)
模型的創建:數據表的設計和同步到數據庫中
1)明確博客文章的組成字段及其類型
?
??
2)定義字段
??
??
?3)文章模型的定義
打開models.py
class Article(models.Model):# 文章idarticle_id = models.AutoField(primary_key=True) # 自增、主鍵# 文章標題,文本類型article_title = models.TextField()# 文章摘要,文本類型article_abstract = models.TextField()# 文章正文,文本類型article_content = models.TextField()# 文章發布日期,日期類型article_data = models.DateTimeField(auto_now=True) # 自己填充當前日期
4)python manage.py makemigrations生成遷移文件
?
?
5)python manage.py migrate 遷移模型到數據庫
遷移模型到數據庫,即創建了一張表到數據庫中
?
?用可視化軟件NAVICAT可以看到在數據庫db.sqlite3中已經創建了一個數據表
數據表命名規則:應用名_模型名
?
?思考:既然模型的創建是數據表的創建,那是否可以直接在可視化軟件Navicat中進行數據表的創建呢?
答:如果單單從數據表的創建來看是可以的,但是我們在使用命令python manage.py migrate進行模型的遷移時有可能不單單創建了數據表,還可能對其他文件的一些參數進行了修改,當然這個目前還不確定。
8、Django shell——交互式環境
1)what&why
?
??
?2)how——向數據庫中插入一條記錄
python manage.py shell進入Django shell環境
?
# 利用Django shell向數據庫中插入一條記錄,即創建一篇文章
>>> a = Article()??? # 類實例化
# 設置各個字段的值
>>> a.article_title = "test django shell"
>>>? a.article_abstract = "abstract"
>>> a.article_abstract = "abstract"
>>> a.article_content = "test django shell content"# 保存記錄到數據庫中
>>> a.save()
>>>
# 獲取模型Article中所有的記錄,即獲取數據表中所有的記錄
>>> articles = Article.objects.all()
>>> artice = articles[0]
>>> print(artice.title)
# 打印指定數據表的某一記錄的字段值
>>> print(artice)
Article object (1)
>>> print(artice.article_title)
test django shell
?
?小結:利用Django shell進行文章的創建(記錄的插入非常的麻煩)
9、Django admin模塊——管理員功能(用于后臺修改數據)
1)what&why
??
?
?2)how——如何使用admin模塊
①創建管理員身份
python manage.py createsuperuser
?
?
②運行admin模塊
python manage.py runserver
?
?輸入賬號密碼
?
?我們看到了可以管理用戶和groups,但是沒有看到articles,這是因為我們還沒有將模型注冊到admin模塊中,因此在admin身份登錄后看不到
③在admin.py中注冊模型
from django.contrib import admin# Register your models here.# 導入模型
from blog.models import Articleadmin.site.register(Article)
?再次執行②
?
??
?但是可以看到每篇文章的標題顯示的都是object格式,無法知道具體文章,因此我們需要在創建模型的時候將文章的title返回,這樣就可以顯示文章標題了
models.py
class Article(models.Model):# 文章idarticle_id = models.AutoField(primary_key=True) # 自增、主鍵# 文章標題,文本類型article_title = models.TextField()# 文章摘要,文本類型article_abstract = models.TextField()# 文章正文,文本類型article_content = models.TextField()# 文章發布日期,日期類型article_data = models.DateTimeField(auto_now=True) # 自己填充當前日期def __str__(self):return self.article_title
?
?10、從數據庫中獲取數據并且返回給瀏覽器
這里涉及到多個文件
view.py:定義一個函數,從模型文件models.py中獲得模型,并且通過模型獲得模型的數據,返回數據給瀏覽器;
models.py:定義了模型,實則就是一張數據表,可以輕松的從數據表中獲取數據,然后視圖
urls.py:定義路由,根據路徑分配到其他地方,然后調用相應的視圖函數
1)編寫代碼
view.py
from django.shortcuts import renderfrom django.http import HttpResponsefrom blog.models import Articledef get_article_contents(request):articles = Article.objects.all()first_article = articles[0]title = first_article.article_titleabstract = first_article.article_abstractcontent = first_article.article_contentreturn_str = "title:%s, abstract:%s, content:%s"%(title,abstract,content)return HttpResponse(return_str)
應用層urls.py
from django.urls import path,include
import blog.viewsurlpatterns = [# 當指派到本應用的路由一級路由名為hello_world時,調用view.py中的hello_world函數path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents)
]
項目層urls.py
rom django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),# 將URL分配到對應的APP當中進行二級路由,這里是將其分配到blob.urls中path("blog/",include("blog.urls"))
]
?
?2)整個過程的流程圖
?
?問題3:什么是Django模板(template)
11、django 模板系統
小結:模板系統其實就是一個文本,內容包含了必要的HTML標簽以及模板特有的標簽占位符組成的。即將之前的HTML文件中的內容用變量來代替了,作為一個HTML模板來使用,等需要使用的時候,只需要向HTML中的變量提供數據即可,這個過程也叫做渲染模板。
1)模板系統簡介
Django模板是一個string文本,它用來分離一個文檔的展現和數據
模板定義了placeholder和表示多種邏輯的tags來規定文檔如何展現
通常模板用來輸出HTML,但是Django模板也能生成其它基于文本的形式
?
??
?2)簡單的模板例子
<html><head><title>Ordering notice</title></head><body><p>Dear {{ person_name }},</p><p>Thanks for placing an order from {{ company }}. It's scheduled toship on {{ ship_date|date:"F j, Y" }}.</p><p>Here are the items you've ordered:</p><ul>{% for item in item_list %}<li>{{ item }}</li>{% endfor %}</ul>{% if ordered_warranty %}<p>Your warranty information will be included in the packaging.</p>{% endif %}<p>Sincerely,<br />{{ company }}</p></body></html>
這個模板本質上是HTML,但是夾雜了一些變量和模板標簽:
- 用{{}}包圍的是變量,如{{person_name}},這表示把給定變量的值插入
- 用{%%}包圍的是塊標簽,如{%if ordered_warranty%}
????????塊標簽的含義很豐富,它告訴模板系統做一些事情
????????在這個例子模板中包含兩個塊標簽:????????for標簽表現為一個簡單的循環結構,讓你按順序遍歷每條數據
????????if標簽則表現為邏輯的if語句
????????在這里,上面的標簽檢查ordered_warranty變量的值是否為True
????????如果是True,模板系統會顯示{%if ordered_warranty%}和{%endif%}之間的內容
????????否則,模板系統不會顯示這些內容
????????模板系統也支持{%else%}等其它邏輯語句
- 上面還有一個過濾器的例子,過濾器是改變變量顯示的方式
????????上面的例子中{{ship_date|date:"F j, Y"}}把ship_date變量傳遞給過濾器
????????并給date過濾器傳遞了一個參數“F j, Y”,date過濾器以給定參數的形式格式化日期
????????類似于Unix,過濾器使用管道字符“|”
????????Django模板支持多種內建的塊標簽,并且你可以寫你自己的標簽
3)Django模板系統的基本語法
?
??
?
12、boostrap以及boostrap柵格系統
其實就是一個前端框架,我們可以利用boostrap系統進行前端網頁的設計和布局,以及在boostrap官網上直接復制HTML代碼下來用于作為模板
??Bootstrap中文網
??
?
?
?
?
??
?可以利用這12份進行布局,比如左右各幾份
13、【實操】利用boostrap和Django模板實現博客系統
1)博客頁面設計(博客首頁+博客文章詳情頁)
博客首頁
?
博客詳情頁
?
2)博客首頁設計
在應用下創建templates文件夾,在templates文件夾下創建blog(應用名)文件夾,blog下創建index.html文件
編輯index.html文件,引入boostrap相關資源,進入官網點擊起步復制相關代碼(這里引入的資源是css和JavaScript文件)
①書寫博客首頁的模板(HTML)
含有變量:article_list和top_article_list
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><!--插入boostrap的相關資源--><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"crossorigin="anonymous"></script>
<!-- <link rel="stylesheet" href="index.css">--><title>定義自己的一個博客網站</title></head>
<body>
<!--定義博客首頁的標題部分-->
<div class="container page-header"><h1>三小時入門<small>——by zls</small></h1>
</div>
<!--定義博客首頁主體部分-->
<div class="container page-body"><!--定義主體部分顯示文章列表部分,占9份--><div class="col-md-9" role="main"><div class="body-main"><!-- 每個文章的信息用一個塊來表示-->{% for article in article_list %}<div><h2>{{article.article_title}}</h2><p>{{article.article_content}}</p></div>{% endfor %}</div></div><!--定義主體部分顯示最近文章列表部分,占3份--><div class="col-md-3" role="complementary"><h2>最新文章</h2>{% for top_article in top_article_list %}<h4><a href="#">{{top_article.article_title}}</a> </h4>{% endfor %}</div></div>
</body>
</html>
?②修改視圖文件函數返回模板變量值
from django.shortcuts import renderfrom django.http import HttpResponsefrom blog.models import Article# 從數據庫獲得所有數據填充到HTML模板中
# 其中render函數就是將變量值數據喂給指定模板
def get_detail_page(request):all_articles = Article.objects.all()return render(request,"blog/index.html",{'article_list':all_articles,'top_article_list':all_articles})
?③設置路由
from django.urls import path,include
import blog.viewsurlpatterns = [# 當指派到本應用的路由一級路由名為hello_world時,調用view.py中的hello_world函數path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_detail_page)
]
?項目層面的路由不變
④python manage.py runserver運行
?
3)博客文章詳情頁設計
在應用下templates文件夾的blog(應用名)文件夾,blog下創建page_detail.html文件
編輯page_detail.html文件,引入boostrap相關資源,進入官網點擊起步復制相關代碼(這里引入的資源是css和JavaScript文件)
①書寫博客首頁的模板(HTML)
含有變量:cur_article
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><!--插入boostrap的相關資源--><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"crossorigin="anonymous"></script><link rel="stylesheet" href="../index.css"><title>文章標題1</title></head>
<body>
<!--定義博客文章詳情頁的標題部分-->
<div class="container page-header"><h1>{{cur_article.article_title}}</h1>
</div>
<!--定義博客詳情頁主體部分-->
<div class="container page-body"><div class="body-main"><p>{{cur_article.article_content}}</p></div>
</div>
</body>
</html>
??②修改視圖文件函數返回模板變量值
# 選取指定文章的內容,這里以第一篇為例
def get_detail_page(request):cur_article = Article.objects.all()[0] # 取第一篇文章return render(request,'blog/page_detail.html',{"cur_article":cur_article,})
?③設置路由?
urlpatterns = [# 當指派到本應用的路由一級路由名為hello_world時,調用view.py中的hello_world函數path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_index_page),path("detail",blog.views.get_detail_page),
]
④python manage.py runserver運行?
?
4)實現博客首頁跳轉至文章詳情頁
①文章詳情頁URL鏈接設計
前面設計的詳情頁URL鏈接是:http://127.0.0.1:8000/blog/detail
為了能夠讓每一個詳情頁URL獨一無二,這里將文章的article_id作為唯一標識,其實就是數據表的主鍵,設計后URL鏈接為:http://127.0.0.1:8000/blog/detail/{article_id}
②修改詳情頁鏈接路由設置
urlpatterns = [# 當指派到本應用的路由一級路由名為hello_world時,調用view.py中的hello_world函數path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_index_page),path("detail/<int:article_id>",blog.views.get_detail_page),
]
③修改視圖函數get_detail_page
# 選取指定文章的內容
def get_detail_page(request,article_id):all_articles = Article.objects.all()cur_article = Nonefor article in all_articles:# 遍歷所有文章,若文章id和指定的id一樣時,獲取文章,停止遍歷if article.article_id == article_id:cur_article = articlebreakreturn render(request,'blog/page_detail.html',{"cur_article":cur_article,})
④為博客首頁的文章列表添加鏈接
<a href = URL>...<a>
<div class="body-main"><!-- 每個文章的信息用一個塊來表示-->{% for article in article_list %}<div><h2><a href="/blog/detail/{{article.article_id}}">{{article.article_title}}</a> </h2><p>{{article.article_content}}</p></div>{% endfor %}</div>
5)實現上下篇文章跳轉
?
?①設計翻頁按鈕——boostrap翻頁組件
<nav aria-label="..."><ul class="pager"><li><a href="#">Previous</a></li><li><a href="#">Next</a></li></ul>
</nav>
將上述代碼添加到detail_page.html中
<body>
<!--定義博客文章詳情頁的標題部分-->
<div class="container page-header"><h1>{{cur_article.article_title}}</h1>
</div>
<!--定義博客詳情頁主體部分-->
<div class="container page-body"><div class="body-main"><p>{{cur_article.article_content}}</p><div><nav aria-label="..."><ul class="pager"><li><a href="#">上一篇:{{previous_article.article_title}}</a></li><li><a href="#">下一篇:{{next_article.article_title}}</a></li></ul></nav></div></div>
</div>
</body>
?
?②給每一個詳情頁的上下篇文章按鈕設置鏈接
blog/detail/article_id
<li><a href="/blog/detail/{{previous_article.article_id}}">上一篇:{{previous_article.article_title}}</a></li>
<li><a href="/blog/detail/{{next_article.article_id}}">下一篇:{{next_article.article_title}}</a></li>
③修改視圖函數
# 選取指定文章的內容
def get_detail_page(request,article_id):all_articles = Article.objects.all()cur_article = Noneprevious_article = Nonenext_article = Nonefor index,article in enumerate(all_articles):# 遍歷所有文章,若文章id和指定的id一樣時,獲取文章,停止遍歷if article.article_id == article_id:cur_article = article# 當當前頁是第一頁且不是最后一頁時,沒有上一頁if index == 0 and index != len(all_articles)-1:previous_article = articlenext_article = all_articles[index+1]# 當當前頁是最后一頁且不是第一頁時,沒有下一頁elif index != 0 and index == len(all_articles)-1:previous_article = all_articles[index-1]next_article = article# 當只有一篇文章時elif index == 0 and index == len(all_articles)-1:previous_article = articlenext_article = articleelse:previous_article = all_articles[index-1]next_article = all_articles[index+1]breakreturn render(request,'blog/page_detail.html',{"cur_article":cur_article,"previous_article":previous_article,"next_article":next_article,})
?
?6)實現博客首頁分頁功能
?
〇Django分頁組件工具——Django.core.paginator.Paginator
功能:可以將一個列表按照指定的長度分割成多個子列表
p = Paginator(列表,每頁的數目)
屬性:
p.num_page:分成了多少頁
p.count:列表的長度
p_index = p.page(index):表示取得第index頁的對象
p_index.object_list:取得第index頁的數據
p_index.has_next():判斷是否有下一頁,有返回True,沒有返回false
p_index.has_previous():判斷是否有上一頁,有返回True,沒有返回false
①設計分頁按鈕——boostrap分頁組件
<nav aria-label="Page navigation"><ul class="pagination"><li><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li></ul>
</nav>
將上面的分頁HTML加入到index.html中
<!--分頁功能--><div class="body-footer"><div class="col-md-4 col-md-offset-3"><nav aria-label="Page navigation"><ul class="pagination"><li><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a></li><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#" aria-label="Next"><span aria-hidden="true">»</span></a></li></ul></nav></div></div></div>
?②設計分頁的URL
可以參考詳情頁翻頁的設計:blog/index/article_id
但是為了學習新知識,這里使用的是:blog/index?page=article_id的方式設計URL
?page=。。。問號后面的參數可以通過request.GET.get('page')來獲取得到
③修改視圖函數
# 從數據庫獲得所有數據填充到HTML模板中
# 其中render函數就是將變量值數據喂給指定模板
def get_index_page(request):# 根據請求的參數獲得請求的是第幾頁page = request.GET.get("page")# 得到第幾頁的參數if page:page = int(page)else:page = 1# 獲取所有的文章articles = Article.objects.all()# 利用Django分頁組件將文章列表進行分頁,每頁顯示3個文章簡介paginator = Paginator(articles, 3)# 根據page獲得當前頁需要顯示的文章頁cur_page_articles = paginator.page(page)# 總頁數total_page_num = paginator.num_pages# 設置上一頁,下一頁# 如果當前頁有下一頁則下一頁加1,否則設置為當前頁if cur_page_articles.has_next():next_page = page + 1else:next_page = page# 如果當前頁有上一頁則上一頁減1,否則設置為當前頁if cur_page_articles.has_previous():previous_page = page - 1else:previous_page = pagereturn render(request,"blog/index.html",{'article_list':cur_page_articles,'top_article_list':articles,'page_num':range(1,total_page_num+1), # 總頁數'previous_page':previous_page,"next_page":next_page})
④修改index.html模板
<!--分頁功能--><div class="body-footer"><div class="col-md-4 col-md-offset-3"><nav aria-label="Page navigation"><ul class="pagination"><li><a href="/blog/index?page={{previous_page}}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>{% for num in page_num %}<li><a href="/blog/index?page={{num}}">{{num}}</a></li>{% endfor %}<li><a href="/blog/index?page={{next_page}}" aria-label="Next"><span aria-hidden="true">»</span></a></li></ul></nav></div></div></div>
總共7篇文章,每一頁顯示3篇文章,分成了3頁
?7)實現最新文章的顯示功能
修改view.py函數即可
# 獲取所有的文章articles = Article.objects.all()# 獲取按照時間排序的的最新的5篇文章,根據發布日期字段進行降序排序top_article_list = Article.objects.order_by("-article_data")[:5]
?
14、總結
?設計一個網頁的流程:
- 創建項目
- 創建應用
- 網頁布局設計
- 模型設計(數據表設計)
- 根據布局設計網頁模板(templates)
- 設計視圖函數view.py
- 利用模板和視圖進行渲染(喂數據)
本項目目錄總覽:
?