DAY12 新聞詳情頁的相關渲染和使用者登入狀態校驗封裝
新聞詳情頁的相關渲染
在我們點選了首頁的新聞標題之後就會跳轉到一個URL
這個URL所展示頁面就是我們渲染新聞詳情頁的頁面,我們需要
新建一個檢視來完成
首先根據地址,需要一個新的藍圖,且字首為news,來到我們專門存放
檢視的modules資料夾,然後新建一個Python資料夾news,並建立一個檔案views
來存放我們的檢視
然後先在news的__init__.py建立我們的藍圖,建立好之後在app中註冊使用,相關的程式碼說明前面有,這裡就不細講了,老
朋友了,放點截圖意思意思。
然後再views裡先匯入這個檢視,之後建立我們的檢視函式
我們主頁跳轉的URL後面會有數字,那個是新聞的ID,我們通過js動態獲取的資料自動生成了這個URL,所以
我們在設定檢視的URL裡面需要設定接收這個數字,用<>裡面的變數名來接收,並進行整形的強轉後作為形參給檢視函式。然後進行
查詢。我們只接收數字
建好檢視之後,還是先寫註釋,函式實現的功能
首先見我們的頁面給渲染出去,然後再根據頁面來進行分析,需要解決哪些問題,這裡詳情頁面的HTML在我們之前的static裡面
,我們將它移動到templates裡面就可以了,還是放在我們的前端相關的news裡
完成之後先執行,然後點選新聞標題來到詳情頁
通過檢視我們發現獲取使用者登入狀態和點選排行我們之前在處理主頁面時都寫過
從index的檢視函式裡把程式碼複製過來就行,紅框就是我們的封裝,後面講
前端HTML也別忘了修改,從index.html中對應的程式碼複製過來進行覆蓋就行
完成之後就行新聞詳情的渲染,也就是新聞相關。
我們需要通過從URL中接收到的新聞ID來進行查詢
第三方資料庫查詢需要異常捕捉,其他的就和前面的查詢沒有什麼區別,通過ID來獲取對應的新聞
但是我們生成上下文時執行了類裡的一個函式,它的作用就是將傳入的物件的所有資料變成字典傳
給前臺,裡面還可以加入一些我們沒有的類屬性,這個很重要。方便我們做資料的傳輸
函式裡還對我們的資料格式也做了處理,這樣直接使用就可以,不需要進行前臺再轉換,以及我們關聯的表的資料進行獲取,比如點贊數
將程式碼簡化。
完成之後,我們把前端的測試資料刪掉,用模板引擎 的寫法換上對應的新聞資料
在渲染內容時會發現出現了一堆標籤,我們這裡就需要我們模板引擎自帶的過濾器safe來進行宣告並讓
瀏覽器進行渲染
對應的替換內容檢視單詞就行
這樣我們點選對應的新聞標題就是我們對應的內容,新聞詳情渲染完成
使用者登入狀態校驗封裝
因為許多的操作需要校驗我們的登入狀態,也就是每一個對應的檢視函式
裡都需要使用和寫入這個功能,我們可以通過建立裝飾器來完成功能的新增
或者將這個部分封裝成函式然後呼叫,這裡我們將裝飾器。
首先這也是一個我們自定義的工具,我們來到我們的自定義工具檔案comment中我們自定義過濾器的後面來建立
程式碼為,裡面執行的是我們獲取session的並查詢的程式碼,沒有的包記得匯入:
def user_login_data(func):
def wrapper(*args,**kwargs):
# 1. 獲取使用者登入狀態
# 1.1從session中獲取user_id
user_id = session.get("user_id")
user = None # 進行預設值的設定,防止資料庫操作錯誤導致上下文裡面沒有變數而報錯
# 1.2利用user_id進行資料庫查詢,將查詢到使用者資訊用變數進行儲存
try:
user = User.query.filter_by(id=user_id).first()
except Exception as e:
current_app.logger.error(e)
abort(404)
g.user = user #g變數來儲存我們的user
return func(*args,**kwargs)
return wrapperz
這裡使用了g變數來儲存我們查詢的user,方便我們在檢視函式中獲取。
g 變數的說明:
g:global
- g物件是專門用來儲存使用者資料的
- g物件在一次請求中的所有的程式碼的地方,都是可以使用的
- g物件傳送第二次請求時,便會失效
這樣我們檢視中獲取使用者的資訊程式碼就變成了
# 1. 獲取使用者登入狀態
user = g.user
不論是在過濾器函式中或者檢視函式中使用時都記得匯入, 過濾器本身就是函式
所以我們需要先匯入後再通過語法糖來進行檢視函式的裝飾使用
新聞詳情頁的全部的程式碼為:
@news_blue.route("/detail/<int:news_id>")
@user_login_data
def detail(news_id):
"""
新聞詳情頁渲染
1.獲取使用者登入狀態
1.1從session中獲取user_id
1.2 利用user_id進行資料庫查詢,將查詢到使用者資訊用變數進行儲存
2.點選排行新聞處理
2.1 通過查詢資料庫獲得點選量對多的前6條資料
3.通過新聞ID獲取詳情
:return:
"""
# 1. 獲取使用者登入狀態
user = g.user
# 2點選排行新聞處理
# 2.1通過查詢資料庫獲得點選量對多的前6條資料
news_click_list = []
try:
news_click_list = News.query.order_by(News.clicks.desc()).limit(6)
except Exception as e:
current_app.logger.error(e)
# print(news_id)
#3通過新聞ID獲取詳情
news = None
try:
news = News.query.filter_by(id=news_id).first()
except Exception as e :
current_app.logger.error(e)
abort(404)
# 生成儲存使用者變數的上下文並傳到前臺進行相關判斷處理
context = {
"user": user,
"news_click_list": news_click_list,
"news":news.to_dict()
}
return render_template("news/detail.html", **context)