Flask專案各模組如何實現,基於新經資訊新聞總結
新聞首頁模組
一、註冊相關介面
(一)圖片驗證碼
1、獲取前端生成的UUID編碼
image_code_id = generate()前端呼叫該方法生成UUID編號,併發送給伺服器
由於這是一個imp標籤所以伺服器可以request.args.get()獲取到這個編碼
2、呼叫captcha(圖靈測試)擴充套件生成圖片驗證碼
對獲取到的引數進行驗證,判斷是否存在
存在則:name,text,image = captcha.generate_captcha()呼叫captcha生成圖片驗證碼
3、以前端獲取的UUID為鍵,captcha生成的text為值,儲存到Redis資料庫中
使用Redis資料庫redis_store.setex(imageCodeId,time,text)將資料進行儲存
4、使用flask中的make_response將圖片返回給前端頁面
response = make_response(image)
5、修改前端相應報頭並返回
response. headers[‘Content-Type’] = ‘image/jpg’
return….
(二)傳送手機簡訊
1、根據介面文件指定請求方式,以及確定需要接受的引數
2、對接受的引數進行校驗
(1)確認引數的完整性
if not all([mobile,image_code,image_code_id])
return…
(2)確認手機號是否符合規範(採用正則的方式驗證)
if not re.match(r‘1[3456789]\d{9}’,mobile)
return…
(3)確認驗證碼是否正確,從Redis資料庫中取出之前儲存的text值進行比對,為防止二次使用驗證碼,取出後刪除資料庫中資料
real_image_code = redis_store.get(image_code_id)
redis_store. delete(…)
if not real_image_code.lower() != image_code.lower()
return…
3、引數校驗完成後判斷使用者是否已經註冊
查詢MySQL資料庫中是否存在該使用者
user = User.query.filter_by(mobile=mobile).first()
if user 表示使用者存在已經註冊
return…
4、生成6位隨機數,並以使用者手機號位鍵,隨機數位值將資料儲存到Redis資料庫
sms_code = ‘%06d’ % random.randint(0,999999)
redis_store.setex(mobile,time,sms_code)
5、呼叫第三方雲通訊介面傳送生成的6位隨機數給使用者手機,
生成6位隨機數:sms_code = ‘%06d’ % random.randint(0,999999)
呼叫雲通訊傳送簡訊:ccp = sms.CCP()
result = ccp.send_template_sms(mobile,[sms_code,time / 60],1)
如果result == 0 表示傳送成功,else傳送失敗
(三)註冊按鈕
1、根據介面文件指定請求方式,以及確定需要接受的引數
2、對接受的引數進行校驗
(1)確認引數的完整性
if not all([mobile,sms_code,password])
return…
(2)確認手機號是否符合規範(採用正則的方式驗證)
if not re.match(r‘1[3456789]\d{9}’,mobile)
return…
(3)確認手機驗證碼是否正確,從Redis資料庫中取出之前儲存的sms_code值進行比對,為防止二次使用,取出後刪除資料庫中資料
real_sms_code = redis_store.get(mobile)
由於之前設定的是有時效的資料,因此需要判斷是否還存在該sms_code
redis_store.delete(…)
if not real_sms_code != str(sms_code)
return…
3、將使用者的資料儲存到MySQL資料庫
user = User()
user.moblie = mobile
user.password = password(加密儲存)
user.nike_name = mobile(給使用者預設設定一個暱稱)
db.session.add(user)
db.session,commit()
4、為實現狀態保持,將使用者的註冊的資訊儲存到Reids資料庫中,並提示註冊完成
session[‘user_id’] = user.id
session['mobile'] = user.mobile
session['nick_name'] = mobile
二、登入相關介面
1、根據介面文件確定需要接受的引數以及請求方式
2、校驗引數的完整性
if not all([mobile,password])
3、判斷手機號碼是否符合規則
if not re.match(r‘1[3456789]\d{9}’,mobile)
return…
4、根據手機號碼進行MySQL的資料查詢
user = User.query.filter_by(mobile=mobile).first()
5、判斷是否存在使用者或則密碼是否正確
if user is None or not user.check_password(password)(呼叫加密密碼的檢查匹對方法)
return
6、儲存使用者的登入資訊並記錄使用者的最後登入時間
session[‘user_id’] = user.id
session['mobile'] = mobile
session['nick_name'] = user.nick_name
user.last_login = datetime.now()
7、記錄的使用者登入時間需要提交到資料庫中
db.session.commit()
8、返回提示使用者登入成功
三、退出相關介面
退出即刪除使用者的登入資訊
session.pop(‘user_id’)
session.pop('mobile')
session.pop(‘nick_name’)
此處建議使用pop()方法,不建議使用clear()方法
四、主頁相關介面
採用模板的方式,所以需要匯入render_template
1、確認使用者是否登入線上
user = g.user //此處是定義的裝飾器
2、展示點選排行按點選量進行排序查詢,且根據前端的設計是顯示的六條資訊
news_list = News.query.order_by(News.clicks.desc()).limit(6)
3、判斷點選排行資料查詢結果是否存在
if not news_list:
return…
4、定義一個列表容器儲存查詢結果
news_dict_list = []
5、遍歷所有的查詢物件並新增到列表容器中,並呼叫模型類中to.dict()的方法將之轉換成字串
for news in news_list:
news_dict_list.append(news.to_dict())
6、展示新聞分類資料需搜尋所有分類資訊
categories = Category.query.all()
7、判斷分類資料是否存在
if not categories:
return
8、定義一個列表容器儲存查詢結果
category_list = []
9、遍歷所有的查詢物件並新增到列表容器中,並呼叫模型類中to.dict()的方法將之轉換成字典
for category in categories:
category_list.append(category.to_dict())
10、定義一個字典儲存所有資料,並將之傳給模板進行資料填充
data = {
"user":user.to_dict() if user else None,//表示如果使用者未登入的情況下也是可以訪問主頁面的
"news_dict_list":news_dict_list,
"category_list":category_list
}
return render_template(‘模板’,data=data)
五、首頁新聞資料列表介面
1、根據介面文件定義路由,請求方式以及需要哪些引數等(備註:ajax/get請求)
2、接受所需要引數並進行校驗(cid,page,per_page)
為實現友好的互動,即使後端沒傳過來資料,在首頁也是需要展示新聞的,所以我們預設會給其定義一個引數
cid = request.args.get(‘cid’,‘1’) è分類id
page = request.args.get('page','1')
per_page = request.args.get('per_page','10')
3、校驗引數,並將數字引數轉換成整型值(為了和資料庫進行查詢)
try:
cid,page,per_page = int(cid),int(page),int(per_page)
except Exception as e:
return
4、根據引數進行查詢資料庫
(1)定義變數,儲存過濾條件è根據分類id
filters = []
if cid > 1: => filters.append(News.category_id == cid)
(2)預設按照分類id進行過濾,按新聞釋出時間進行排序,對查詢資料進行分頁
paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page,per_page,False)
paginate(頁數,每頁多少條目數,分頁異常不報錯)
5、獲取分頁後的新聞資料模型物件,總頁數以及當前頁數
news_list = paginate.items //模型物件
total_page = paginate.pages //總頁數
current_page = paginate.page //當前頁數
6、遍歷模型物件並新增到一個列表容器,使用to_dict()方法轉換成字典
for news in news_list:
news_dict_list.append(news.to_dict())
7、準備返回資料:
(1) data = {
(2) ‘news_dict_list’:news_dict_list,
(3) ‘total_page’:total_page,
(4) ‘current_page’:current_page
(5) }
8、進行返回 return jsonify(errno=RET.OK,errmsg=‘OK’,data=data)
新聞詳情頁模組
一、詳情頁模板介面
1、獲取引數以url傳參的形式獲取引數
def get_news_detail(news_id):
2、判斷使用者是否登入線上,並獲取使用者資訊
user = g.user
3、根據news_id進行查詢資料庫
news = News.query.get(news_id)
4、檢查查詢的結果
if not news:
return…
5、展示詳情頁的分類資料,查詢資料庫
categories = Category.query.all()
6、檢查查詢的結果,並定義容器儲存遍歷的查詢物件
if not categories:
return…
7、將新聞詳情的點選次數 +1
news.clicks += 1
8、判斷是否收藏,預設情況為False,如果使用者已經登入,並且被該使用者收藏
is_collected = False
if user and news in user.collection_news:
is_collected = True
9、評論內容,查詢資料庫獲取當前新聞的所有評論
comments = []
comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
10、判斷使用者登入
if user:
獲取所有的評論id
comment_ids = [comment.id for comment in comments]
再查詢當前使用者點讚了哪些評論
comment_likes = CommentLike.query.filter(CommentLike.comment_id.in_(comment_ids),CommentLike.user_id == g.user.id).all()
獲取當前使用者點讚的評論id
comment_like_ids = [comment_like.comment_id for comment_like in comment_likes]
11、定義一個列表使用者來儲存評論資料
comment_dict_li = []
12、遍歷查詢到所有評論資料
for comment in comments:
comment_dict = comment.to_dict()
判斷評論是否被點贊,預設為False
comment_dict['is_like'] = False
if comment.id in comment_like_ids:
comment_dict['is_like'] = True
將查詢到的點讚的評論資料儲存到之前定義的列表中
comment_dict_li.append(comment_dict)
13、如果使用者是登入的,查詢使用者關注的新聞釋出者,預設為Falas
is_followed = False
if news.user and user:
if news.user in user.followers:
is_followed = True
14、將所有資料新增到一個字典容器中
data = {
"news":news.to_dict(),
"category_list":category_list,
'user': user.to_dict() if user else None,//如果使用者未登入,那麼有關使用者的資訊就為False,新聞詳情頁沒必要規定使用者必須線上
'is_collected': is_collected,
'is_followed': is_followed,
'comments': comment_dict_li
}
15、呼叫模板頁面返回資料,並對模板進行資料填充顯示
return render_template('news/detail.html',data=data)
二、收藏和取消收藏介面
根據介面文件進行路由分析,指定請求方式
1、嘗試獲取使用者資訊,如果使用者未登入,需提示使用者登入,才能進行收藏
user = g.user
if not user:
return…
2、獲取引數news_id,action(collect,cancle_collect)
request.json.get()方法獲取
3、檢查引數,對news_id強轉為整型值,對資料庫進行查詢,如果強轉出錯返回錯誤資訊
4、檢查action的值是否存在
if action not in [‘collect’, ‘cancel_collect’]:
return…
5、判斷新聞是否存在資料庫中
news = News.query.get(news_id)
if not news:
return…
6、判斷選擇的是collect還是cancle_collect,並判斷使用者是否收藏過該新聞,未收藏過新增到收藏,收藏過返回已收藏
if action == collect:
if news not in user.collection_news:
user.collection_news.append(news)
else:
If news in user.collection_news:
User.collection_news.remove(news)
7、提交資料庫
8、返回ajax響應資訊
三、關注和取消關注介面
與收藏介面類似,只需根據介面文件定好路由以及請求方式,不過多贅述
四、新聞評論介面
根據介面文件確定路由及請求方式
1、獲取使用者登入資訊,如果使用者未登入直接返回並提示登入
user = g.user
2、獲取引數,news_id,comment,parent_id(回覆的評論的id)
request.json.get()方法
3、校驗引數完整性
if not all([news_id,comment]):
return…
4、對news_id進行強轉,並判斷是否有parent_id,如果強轉失敗返回錯誤資訊
news_id = int(news_id)
if parent_id:
parent_id = int(parent_id)
5、查詢新聞並判斷新聞是否存在
news = News.query.get(news_id)
if not news:
return…
6、例項化評論模型的物件,並新增資料
comment = Comment()
comment.user_id = user.id
comment.news_id = news.id
comment.content = comment_conent
7、判斷父評論是否存在,存在則新增父評論的資訊
if parent_id:
comment.parent_id = parent_id
8、提交資料到資料庫
try:
db.session.add(comment)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
9、返回評論資料給前端ajax
五、點贊和取消點贊介面
根據介面文件確定路由及請求方式
1、獲取使用者登入資訊,如果使用者未登入直接返回並提示登入
user = g.user
2、獲取引數,comment_id,action(add,remove)
request.json.get()方法
3、校驗引數完整性
if not all([comment_id,action])
return…
if action not in [add,remove]
return…
4、把comment_id轉成整型,強轉錯返回錯誤資訊
5、根據comment_id查詢資料
comment = Comment.query.get(comment_id)
6、判斷查詢結果,如果不存在,返回錯誤資訊
7、判斷action引數是否為add或者remove
(1)如果為add,判斷行為是點贊還是取消點贊,使用CommentLike進行過濾查詢(user_id,comment.id)
comment_like_model = CommentLike.query.filter(CommentLike.user_id == user.id, CommentLike.comment_id == comment.id).first()
if not comment_like_model:è 點贊行為,點贊數加1
comment_like_model = CommentLike()
comment_like_model.user_id = user.id
comment_like_model.comment_id = comment.id
db.session.add(comment_like_model)
comment.like_count += 1
(2)否則為取消點贊 è 取消點贊,點贊數減1
db.session.delete(comment_like_model)
comment.like_count -= 1
8、將資料提交到資料庫中
db.session.commit()
9、返回結果給ajax
個人中心模組
基於iframe進行實現,子頁面的資料更新之後需要同步主頁面相關聯資料,可以採用js進行實現,本專案即採用了ajax的資料互動方式
一、使用者頁面介面
這裡我們用到的是之前就定義好的裝飾器來獲取的使用者資訊
1、獲取使用者資訊
user = g.user
2、判斷是否獲得了使用者的資訊,如果沒有則重定向到主頁
if not user:
return redirect(‘/’)
3、將獲取的使用者資訊使用字典容器儲存起來
4、將資料返回給user.html模板,進行頁面顯示
二、使用者基本資訊展示和修改介面
根據介面文件確定路由以及請求方式[‘GET’,‘POST’]
1、判斷請求方式,預設GET請求載入模板頁面,可以直接以裝飾器獲取到使用者的資訊進行返回
user = g.user
if request.method == ‘GET’:
將使用者資訊返回給模板
return… è 模板為:user_base_info.html
2、獲取引數(signature,nick_name,gender(男,女))
request.json.get()方法
3、校驗引數的完整性
if not all([signature,nick_name,gender])
return…
4、檢查引數gender引數
if gender not in [‘MAN’,‘WOMEN’]
return…
5、使用user物件將使用者的基本資訊儲存到資料庫
user.signature = signature
user.nick_name = nick_name
user.gender = gender
try:
db.session.add(user)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
6、返回結果
三、上傳使用者頭像介面
根據介面文件確定路由以及請求方式[‘GET’,‘POST’]
1、判斷請求方式,預設GET請求載入模板頁面,可以直接以裝飾器獲取到使用者的資訊進行返回
user = g.user
if request.method == ‘GET’:
將使用者資訊返回給模板
return… è 模板為:user_pic_info.html
2、獲取引數(avatar)
request.files.get()方法
3、校驗引數是否存在
if not avatar:
return…
4、使用read()方法讀取圖片的二進位制資料並儲存
avatar_data = avatar.read()
5、呼叫第三方介面storage(),將圖片上傳到七牛雲,並儲存七牛雲返回的圖片名稱
image_name = storage(avatar_data)
6、給使用者儲存圖片的名稱並提交到到資料庫
user.avatar_url = image_name
try:
db.session.add(user)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
7、拼接圖片的絕對路徑並返回給ajax
設定的七牛雲地址 + image_name
四、修改使用者密碼介面
根據介面文件確定路由以及請求方式[‘GET’,‘POST’]
1、判斷請求方式,預設GET請求載入模板頁面
if request.method == ‘GET’:
return… è 模板為:user_pass_info.html
2、獲取引數(old_password,new_password)
request.json.get()方法
3、檢查引數完整性
if not all([old_password,new_password])
return…
4、獲取使用者資訊,並比較使用者輸入的舊密碼,驗證是否正確
user = g.user
if not user.check_password(old_password):
return…
5、驗證成功後儲存使用者的新密碼,並提交到資料庫
user.password = new_password
try:
db.session.add(user)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
6、返回結果給ajax
五、新聞釋出介面
根據介面文件確定路由以及請求方式[‘GET’,‘POST’]
1、判斷請求方式,預設GET請求載入模板頁面
if request.method == ‘GET’:
查詢新聞分類,與新聞首頁模組的主頁相關介面6、7、8、9雷同
return… è 模板為:user_ news_release.html
2、獲取請求引數
request.form.get()方法獲取表單引數
request.files.get()方法獲取新聞圖片引數
3、校驗引數完整性
if not all([title,category_id,digest,index_image,content]):
return…
4、強轉分類id,如果報錯直接返回錯誤資訊
5、read()方法讀取獲取的新聞圖片的二進位制資料並呼叫第三方七牛雲介面上傳圖片,並儲存返回的圖片名稱
image_data = index_image.read()
image_name = storage(image_data)
6、例項化新聞類物件,用來儲存新聞資料
news = News() è 新聞類物件
news.title = title è 新聞標題
news.source = '個人釋出' è 新聞釋出機構
news.category_id = category_id è 新聞分類id
news.digest = digest è 新聞摘要
news.index_image_url = 設定的七牛雲地址 + image_name è 新聞圖片絕對路徑
news.content = content è 新聞內容
news.status = 1 è 新聞狀態,1表示待稽核,0表示稽核通過,-1表示未通過稽核
7、提交資料到資料庫中
六、使用者新聞列表介面
根據介面文件確定路由和請求方式
1、獲取引數,頁數,預設1
request.args.get()方法
2、校驗引數,將page強轉為整型,如果報錯直接返回錯誤資訊
3、獲取使用者資訊,定義容器儲存查詢結果,總頁數預設1,當前頁預設1
4、查詢資料庫,查詢新聞資料並進行分頁,
user = g.user
paginate = News.query.filter(News.user_id==user.id).paginate(page,每頁資料數目 ,False)
可參看新聞首頁模組的新聞列表介面
5、返回資料給模板:user_news_list.html
七、使用者關注資訊介面
根據介面文件確定路由和請求方式
與使用者新聞列別介面流程類似
返回資料給模板:user_follow.html
八、查詢使用者關注的其他使用者資訊
根據介面文件確定路由和請求方式
1、獲取使用者的登入資訊
user = g.user
2、獲取引數other_id(使用者關注的使用者)
request.args.get()方法
3、校驗引數是否存在,如果不存在,返回錯誤資訊
4、查詢資訊
other = User.query.get(other_id)
5、判斷新聞是否有作者,且使用者關注過作者,預設為False
is_follwed = False
if other and user:
if other in user.followed:
is_follwed = True
6、返回資料給模板:other.html
九、返回指定使用者釋出的新聞介面
根據介面文件確定路由和請求方式
1、獲取引數(user_id,頁數預設為1)
request.args.get()方法獲取
2、校驗引數,強轉頁數的引數,如果報錯,直接返回錯誤資訊
3、判斷使用者是否存在
other = User.query.get(user_id)
if not other:
return…
4、如果使用者存在,分頁使用者釋出的新聞資料
paginate = other.news_list.paginate(page,每頁條目數,False)
5、獲取分頁資料,並遍歷資料
news_list = paginate.items
current_page = paginate.page
total_page = paginate.pages
6、返回資料給ajax
後臺管理模組
主要是為了方便網站的管理而建立的後臺管理員模組。管理員與普通使用者公用一張表,管理員也具有普通使用者的功能,用指定的欄位區分普通使用者和管理員使用者,管理員可以登入到後臺管理頁面對新聞以及相應的資料進行操作。
一、建立管理員
使用flask-script擴充套件自定義指令碼命令,以自定義函式的形式實現建立管理員使用者
@manage.option(’-n’,’-name’,dest=‘name’)
@manage.option(’-p’,’-password’,dest=‘password’) //使用指令碼擴充套件必須要的裝飾器函式
def create_supperuser(name,password): //定義建立管理員的函式,並傳入使用者名稱和密碼引數
if not all([name,password]): //校驗引數完整性
print('引數缺失')
user = User() //建立模型類User的物件
user.nick_name = name // 新增相應的資料
user.mobile = name
user.password = password
user.is_admin = True
try: //提交資料到資料庫
db.session.add(user)
db.session.commit()
except Exception as e:
db.session.rollback()
print(e)
print('管理員建立成功')
最後使用終端命令列建立管理員使用者
python manage.py 函式名 -n 使用者名稱 -p 密碼
二、管理員登入請求鉤子的應用 è 判斷當前登入的使用者是否是管理員,並且判斷當前訪問的url是否是管理員登入的頁面url
因為後臺管理不需要讓每個普通使用者都知道,所以在每次請求前先判斷,在後臺管理的模組中的建立藍圖的模組中就可使用before_request請求鉤子實現該功能。具體方式如下:(在後臺管理模組的 init.py 檔案中)
@admin_blu.before_request //每次的請求之前執行的請求鉤子
def check_admin():
is_admin = session.get("is_admin", False) //從Redis資料庫中獲取使用者登入狀態的資訊,預設為False
//判斷獲取的is_admin,如果不是False表示是管理員,並判斷訪問的頁面是否是管理員登入頁面的url,否則返回主頁,終止後續操作。
if not is_admin and not request.url.endswith(url_for(‘admin.login’)):
return redirect('/') //使用重定向返回到主頁頁面
三、後臺管理首頁介面
定義路由,返回後臺管理首頁模板頁面
@admin_blu.route(’/index’) //定義路由
@login_required //確認使用者是否登入
def index():
user = g.user //獲取使用者相關資訊
return render_template('admin/index.html',user=user.to_dict()) //返回後臺管理首頁模板
四、後臺管理員登入介面
定義路由,指定請求方式(GET,POST)
1、如果為GET請求,使用session獲取登入資訊。
request.method == ‘GET’
2、判斷使用者是否登入並且是管理員,則重定向到後臺管理頁面
if user_id and is_admin:
return redirect(url_for(‘後臺管理頁面模板’)
3、否則返回後臺管理登入頁面模板
return render_template(‘後臺管理登入頁面’)
4、POST請求方式下獲取引數(user_name,password)
request.form.get()方法
5、校驗引數完整性
if not all([user_name,password]):
return…
6、查詢資料庫,並判斷使用者密碼是否正確
user = User.query.filter(User.mobileuser_name,User.is_adminTrue).first()
if user is None or not user.check_password(password):
return…
7、快取使用者資訊,實現狀態保持
session[‘user_id’] = user.id
session['mobile'] = user.mobile
session['nick_name'] = user.nick_name
session['is_admin'] = user.is_admin
8、重定向到後來管理首頁
return redirect(url_for(‘admin.index’))
五、後臺使用者資料展示介面
定義路由,獲取資料一般預設為GET請求
1、根據頁面顯示內容包括總人數,月新增人數,日新增人數
2、查詢資料庫統計總人數,排除管理員使用者的所有普通使用者
總人數 = User.query.filter(User.is_admin == False).count()
3、查詢資料庫統計月新增人數,排除管理員使用者的所有普通使用者
(1)使用time模組獲取時間物件(tm_year=2018, tm_mon=6, tm_mday=9)
t = time.localtime()
(2)通過時間物件生成每月開始日期的字串
mon_begin_date_str = ‘%d-%02d-01’ %(t.tm_year,t.tm_mon)
(3)使用strptime()方法將日期的字串轉換成日期物件
mon_begin_date = datetime.strptime(mon_begin_date_str,’%Y-%m-%d’)
(4)作為過濾條件查詢資料庫,獲取月新增人數
mon_count = User.query.filter(User.is_admin == False,User.create_time > mon_begin_date).count()
4、查詢資料庫統計日新增人數,排除管理員使用者的所有普通使用者
具體步驟同統計月新增人數方式,先獲取當前日期,生成字串,再轉換成日期物件,查詢資料庫加上過濾條件,獲取日新增使用者資料
5、實現統計活躍人數/活躍日期
定義列表容器儲存活躍人數,和活躍日期
(1)獲取當前日期,生成字串,再轉換成日期物件
today_begin_date_str = ‘%d-%02d-%02d’ %(t.tm_year,t.tm_mon,t.tm_mday)
today_begin_date = datetime.strptime(today_begin_date_str,'%Y-%m-%d')
(2)遍歷日期,獲取每天的開始日期和結束日期
for x in range(0,31): //一個月按30天
//開始時間,即每天的0時0分
begin_date = today_begin_date - timedelta(days=x) //timedelta()代表兩個時間之間的時間差,兩個data或datatime
//結束時間,即第二天的0時0分 //物件相減就可以返回一個timedelta物件,傳入的引數表示前多少天
end_date = today_begin_date - timedelta(days=(x-1))
(3)使用時間的過濾條件查詢資料庫統計活躍日期的活躍人數
count = User.query.filter(User.is_admin == False, User.last_login >= begin_date, User.last_login < end_date).count()
(4)將需要的資料新增到之前定義的列表中
active_time.append(begin_date_str)
active_count.append(count)
6、定義字典儲存所需資料,將之返回給指定的模板進行渲染
data = {……}
return render_template(‘admin/user_count.html’,data=data)
六、後臺使用者列表展示介面
1、獲取引數,頁數,預設為1
request.args.get()方法
2、校驗引數,強轉為int型別,如果錯誤,直接返回錯誤資訊
3、查詢資料庫獲取使用者列表資訊採用分頁查詢方式
paginate = User.query.filter(User.is_admin==False).paginate(page, 每頁數目, False)
提取查詢結果
current_page = paginate.page
total_page = paginate.pages
users = paginate.items
4、定義容器,遍歷查詢結果,並新增到容器中
for user in users:
user_dict_list.append(user.to_admin_dict())
5、返回資料到指定的模板進行渲染
return render_template(‘admin/user_list.html’, data=data)
七、後臺新聞稽核展示介面
1、獲取引數,(頁數,預設為1,關鍵字引數,預設為None)
request.args.get()方法
2、校驗引數,強轉頁數為int型別,如果錯誤,直接返回錯誤資訊
3、初始化變數,news_list[],current_page = 1,total_page = 1
4、設定過濾查詢條件,當新聞狀態不為0的情況下查詢新聞資料
filters = [News.status != 0]
5、判斷關鍵字引數是否存在,如果存則新增關鍵字搜尋到過濾查詢條件中
if keywords:
filters.append(News.title.contains(keywords))
6、根據引數,進行分頁過濾查詢資料庫並提取查詢結果
paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page, constants.ADMIN_NEWS_PAGE_MAX_COUNT, False)
提取查詢結果
news_list = paginate.items
current_page = paginate.page
total_page = paginate.pages
7、遍歷查詢到的物件,組織資料返回給指定模板渲染
return render_template(‘admin/news_review.html’, data=data)
八、後臺新聞詳情展示介面
通過url傳入新聞id的引數,如下定義路由
@admin_blu.route(’/news_review_detail/int:news_id’)
def news_review_detail(news_id):
……
1、根據news_id查詢新聞詳情資料
news = News.query.get(news_id)
2、校驗查詢結果,如果未查到返回給指定模板錯誤資訊
if not news:
return render_template('admin/news_review_detail.html',data={'errmsg':'未查到資料'})
3、查詢到結果呼叫to_dict()方法再傳回指定模板渲染資料
return render_template(‘admin/news_review_detail.html’,data= {“news”:news.to_dict()})
九、後臺新聞稽核介面
根據需求,應該為POST請求,定義路由指定請求方式
1、獲取引數(新聞id,action)
request.json.get()方法
2、校驗引數完整性
if not all([news_id,action]):
return…
3、校驗action引數是否為accept或reject
if action not in [accept,reject]:
return…
4、根據新聞id查詢資料庫
news = News.query.get(news_id)
5、判斷是否查詢到資料
if not news:
return…
6、判斷action的具體值,accept表示接受,reject表示拒絕
如果為accept修改新聞狀態為 0
如果為reject修改新聞狀態為 -1
7、如果拒絕,接受拒絕原因
request.json.get()方法,獲取拒絕內容
8、判斷是否接受到接受原因,未接受到返回錯誤資訊
9、將資料提交到資料庫
try:
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
10、返回資訊
十、後臺新聞版式編輯介面
1、獲取引數(頁數預設為1,關鍵字引數預設為None)
request.args.get()方法獲取
2、校驗引數,強轉頁數為int型別,如果錯誤,直接返回錯誤資訊
3、初始化變數,news_list[],current_page = 1,total_page = 1
4、定義過濾條件,並判斷關鍵字引數是否存在,如果存在,新增到過濾條件中
filters = [News.status != 0]
if keywords:
filters.append(News.title.contains(keywords))
5、根據相關資料進行分頁查詢資料庫,並儲存到之前初始化的遍歷中
paginate = News.query.filter(*filters).paginate(page,每頁數目,False)
news_list = paginate.items
current_page = paginate.page
total_page = paginate.pages
6、遍歷查詢資料物件,呼叫to_basic_dict()方法
news_dict_list = [] //定義一個容器接受
for news in news_list:
news_dict_list.append(news.to_basic_dict())
7、組織好資料返回給指定的模板進行渲染
return render_template(‘admin/news_edit.html’,data=data)
十一、後臺新聞編輯詳情介面
根據需求判斷,應該是GET請求和POST請求,定義路由,和請求方式
1、判斷是否是GET請求
2、獲取引數新聞id,校驗引數存在,強轉int,如果錯誤,返回錯誤
3、根據新聞id獲取新聞資料
4、校驗查詢資料是否存在,查詢錯誤或則查詢失敗直接返回給指定模板錯誤資訊
5、查詢分類資訊並移除最新分類,使用pop方法
6、遍歷分類資訊,並判斷當前遍歷到的分類和新聞所屬分類是否一致
8、所有條件成立的情況下,組織資料返回給指定模板進行渲染
9、如果為POST請求,獲取引數(news_id,title,digest,content,index_image,category_id)
request.form.get()獲取表單中的資料
request.files.get()獲取圖片檔案
10、校驗引數完整性,與之前大同小異
11、根據新聞id查詢資料庫,確認新聞是否存在,與之前大同小異
12、讀取圖片資料,呼叫第三方介面(七牛雲)上傳圖片並儲存七牛雲返回的圖片名稱,拼接圖片的絕對路徑
13、將資料儲存到資料庫進行提交
14、返回結果。(大部分操作可參照個人中心模組新聞釋出介面)
十二、後臺新聞分類修改介面
根據需求判斷請求方式應該為GET和POST,定義路由
1、判斷如果是GET請求
2、查詢所有分類資料,遍歷查詢結果,並移除最新分類(使用pop()方法)
3、組織資料返回給指定模板進行渲染
4、如果是POST請求
5、獲取引數(name,cid) //如果有cid表示編輯已存在的分類
request.json.get()方法獲取
6、校驗引數name的存在
7、判斷cid是否存在,如果存在即修改已有的分類,強轉為int型別
8、根據分類cid查詢資料庫,校驗查詢結果
9、修改cid的分類資訊為name的值
10、例項化分類模型類的物件,儲存分類名稱,並將資料庫提交到資料庫
11、返回結果