【django學習】——Django介紹和實戰(開發簡易版博客網頁)

目錄

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 | Djangohttps://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">&laquo;</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">&raquo;</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">&laquo;</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">&raquo;</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">&laquo;</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">&raquo;</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
  • 利用模板和視圖進行渲染(喂數據)

本項目目錄總覽:

?

15、問題遺留

1)如何將網頁上用戶輸入的信息保存到數據庫

2)除了boostrap前端框架是否還有其他前端框架

3)實現一個網頁版管理系統

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255619.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255619.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255619.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

求最大子數組03

題目: 返回一個二維整數數組中最大聯通子數組的和。 要求&#xff1a; 1. 輸入一個二維整形數組&#xff0c;數組里有正數也有負數。 求所有子數組的和的最大值。要求時間復雜度為O(n)。 2.程序要使用的數組放在一個叫 input.txt 的文件中&#xff0c; 文件格式是: 數組的行…

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead.

使用VS2005以上版本&#xff08;VS2005、VS2008、VS2010&#xff09;編譯在其他編譯器下正常通過的C語言程序&#xff0c;你可能會遇到類似如下的警告提示&#xff1a;引用內容 warning C4996: strcpy: This function or variable may be unsafe. Consider using strcpy_…

糾錯——【Singleton array array(0.2) cannot be considered a valid collection.】

# 將數據集按照比例劃分為訓練集和測試集 def split_datas(datas,labels,random_state1,train_size0.9,test_size0.1):train_data, test_data, train_label, test_label sklearn.model_selection.train_test_split(datas,labels,random_staterandom_state,# 作用是通過隨機數來…

Android Studio 模擬器 不要皮膚,效果更好

新建或者編輯虛擬機時&#xff0c;皮膚選擇“No Skin”即可&#xff0c;第二張圖片就是無皮膚的效果&#xff0c;看著更爽啊。 轉載于:https://www.cnblogs.com/toSeeMyDream/p/6265501.html

SqlServer自定義排序

在實際項目中&#xff0c;有時會碰到數據庫SQL的特殊排序需求&#xff0c;舉幾個例子&#xff0c;作為參考。 1、自定義優先級 一種常見的排序需求是指定某個字段取值的優先級&#xff0c;根據指定的優先級展示排序結果。比如如下表&#xff1a; Create TABLE Fruit (id INT ID…

JAVA 筆記(三)

NullPointerException:空指針異常 原因&#xff1a;數組已經不再指向堆內存了。而你還用數組名去訪問元素。對于查找問題&#xff0c;如果找到就返回其索引值&#xff0c;如果找不到就要返回一個負數&#xff08;一般是負一&#xff09;這是必須的&#xff0c;否則如果找不到&a…

ERROR: SampleCB() - buffer sizes do not match 解決方法

筆記本有內置攝像頭。Windows7驅動已經安裝成功&#xff0c;利用QQ測試攝像頭正常。但是利用OpenCV簡單的攝像頭操作后&#xff0c;就會出現ERROT: SampleCB() - buffer sizes do not match的問題。下面是代碼&#xff1a; #include<iostream> #include <opencv2/co…

安裝Wamp后 Apache無法啟動的解決方法

安裝Wamp后 Apache無法啟動的解決方法&#xff0c;網上的解決方案可以說是五花八門&#xff0c;有些說了一大推&#xff0c;一點作用都起不到。 其實解決方法只需兩步&#xff1a; 1、安裝路徑不能包含有中文&#xff0c;這個我不知道為什么&#xff0c;總之如果安裝路徑中包含…

MySQL的my.cnf文件(解決5.7.18下沒有my-default.cnf)

官網說&#xff1a;從5.7.18開始不在二進制包中提供my-default.cnf文件。參考&#xff1a;https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html 經過測試&#xff0c;在5.7.18版本中&#xff0c;使用tar.gz安裝時&#xff0c;也就是壓縮包解壓出來安裝這種&…

【Not all parameters were used in the SQL statement】

在添加游標的時候&#xff0c;添加preparedTrue cursor mydb.cursor(preparedTrue) 感謝博主&#xff1a; 【已解決】Python MySQL: Not all parameters were used in the SQL statement - MoonYear530 - 博客園一、事故緣起 今天構造了一個超過 50 多個參數的 SQL 插入語句…

opencv 文件模塊 解析

OpenCV包括以下幾個模塊&#xff0c;具體功能是&#xff1a; 1、CV&#xff1a;主要的OpenCV函數 2、CVAUX&#xff1a;輔助的&#xff08;實驗性的&#xff09;OpenCV函數 3、CXCORE&#xff1a;數據結構與線性代數支持 4、HIGHGUI&#xff1a;圖像界面函數 5、ML&#xff1a;…

解決Android Studio報錯:DefaultAndroidProject : Unsupported major.minor version 52.0

問題描述 今天使用Android Studio 2.0打開我之前的項目時&#xff0c;編譯報了如下錯誤&#xff1a; Error:Cause: com/android/build/gradle/internal/model/DefaultAndroidProject : Unsupported major.minor version 52.0 其中build.gradle文件內容如下所示&#xff1a; // …

Alpha 通道的概念與功能

RGBA采用的顏色是RGB&#xff0c;可以屬于任何一種RGB顏色空間&#xff0c;但是Catmull和Smith在1971至1972年間提出了這個不可或缺的alpha數值&#xff0c;使得alpha渲染和alpha合成變得可能。提出者以alpha來命名是源于經典的線性插值方程αA (1-α)B所用的就是這個希臘字母…

【ValueError: Target is multiclass but average=‘binary‘. Please choose another average setting, one 】

完整報錯為&#xff1a;ValueError: Target is multiclass but averagebinary. Please choose another average setting, one of [None, micro, macro, weighted]. 解決方法 對于多分類任務&#xff0c;將 from sklearn.metrics import f1_score f1_score(y_test, y_pred) 改為…

debian apt-get聯網安裝mysql服務

安裝mysql和卸載mysql 1.安裝數據庫&#xff1a;sudo apt-get install mysql-server 安裝過程中需要設置密碼。 2.安裝客戶端&#xff1a;sudo apt-get install mysql-client 3.登錄MySQL&#xff1a;mysql -u root -p 4.配置文件&#xff1a;/etc/mysql/my.cnf a.設…

【資料下載區】【iCore、 iCore2相關資料】更新日期2017/1/11

【新產品發布】【iCore2 ARM / FPGA 雙核心板】 【iCore系列核心板視頻教程】之 SDRAM 讀寫實驗 【iCore雙核心組合是開發板例程】【uCGUI 例程及代碼包下載】【iCore雙核心組合是開發板例程】【12個 verilog 中級實驗例程發布】【iCore、iCore2 雙核心板】EPCS 實驗&#xff0…

圖像數據格式基礎知識

JPEG文件格式簡單分析 作者&#xff1a;小爽 摘要&#xff1a; 這篇文章大體上介紹了JPEG文件的結構信息以及它的壓縮算法和編碼方式。使讀者能夠對JPEG文件格式有大體上的了解。為讀者進一步進行學習JPEG文件壓縮做好準備 關鍵字&#xff1a;十六進制&#xff0c;段格式&am…

SQL語句:從一個表里按年份統計條目數

比如一個數據表名稱叫deploypool&#xff0c; 需要知道里面每一年的記錄數&#xff0c; 而add_date字段里有增加記錄時的時間&#xff0c; 那么語句如下&#xff1a; SELECT EXTRACT(YEAR from add_date),COUNT(id) FROM deploypool GROUP BY EXTRACT(YEAR from add_date);

為什么需要架構圖,怎么畫?

Technorati 標簽: 架構圖,架構,交流,布局不知不覺中做架構師也已經4年了&#xff0c;最初的感覺只是一個名號&#xff0c;不再把代碼作為強制的任務&#xff0c;后來開始慢慢的轉變工作內容。畫圖&#xff0c;成為了我的主要工作。我可能不是每天都在寫代碼&#xff0c;但卻是每…

Jenkins構建時間Poll Scm的設置(常用設置)

每15分鐘構建一次&#xff1a;H/15 * * * * 或*/5 * * * * 每天8點構建一次&#xff1a;0 8 * * * 每天8點~17點&#xff0c;兩小時構建一次&#xff1a;0 8-17/2 * * * 周一到周五&#xff0c;8點~17點&#xff0c;兩小時構建一次&#xff1a;0 8-17/2 * * 1-5 每月1號、15號…