web应用框架——Flask实践项目(四)
2020-06-29 本文已影响0人
思君_4cd3
一、修改登录信息
- 打开info/modules/index/views.py文件
def index():
#return "index"
"""首页显示"""
#获取当前登录用户的信息(id
user_id = session.get("user_id")
#通过id查询用户信息
user = None
if user_id:
try:
user = User.query.get(user_id)
except Exception as e:
current_app.logger.error(e)
return render_template('news/index.html',data={"user_info":user.to_dict() if user else None})
- 打开info/templates/news/index.html文件
{% if data.user_info %}
<div class="user_login fr">
{# <img src="../../static/news/images/person01.png" class="lgin_pic"> #}
<img src="{% if data.user_info.avatar_url %}{{ data.user_info.avatar_url }}
{% else %}../../static/news/images/person03.png
{% endif %}" class="lgin_pic">
<a href="#">{{ data.user_info.nick_name }}</a>
<a href="#">退出</a>
</div>
{% else %}
<div class="user_btns fr">
<a href="javascript:;" class="login_btn">登录</a> / <a href="javascript:;" class="register_btn">注册</a>
</div>
{% endif %}
-
在数据库中修改姓名
-
运行程序
二、退出登录
- 打开info/modules/passport/views.py文件
#退出
@passport_blu.route('/logout', methods=['POST'])
def logout():
"""清除session中用户的信息"""
session.pop("user_id",None)
session.pop("mobile",None)
session.pop("nick_name",None)
return jsonify(errno=RET.OK,errmsg="OK")
- 打开info/templates/news/index.html文件
<a href="#" onclick="logout()">退出</a>
-
运行程序
三、点击排行
- 打开info/modules/index/views.py文件
def index():
#return "index"
"""首页显示"""
#获取当前登录用户的信息(id
user_id = session.get("user_id")
#通过id查询用户信息
user = None
news_list = None
if user_id:
try:
user = User.query.get(user_id)
except Exception as e:
current_app.logger.error(e)
try:
news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
except Exception as e :
current_app.logger.error(e)
click_news_list = []
for news in news_list if news_list else []:
click_news_list.append(news.to_basic_dict())
data = {
"user_info":user.to_dict() if user else None,
"click_news_list":click_news_list,
}
return render_template('news/index.html',data=data)
- 打开info/templates/news/index.html文件
{% for news in data.click_news_list%}
<li><span class="{{ loop.index0|index_class }}">{{ loop.index }}</span><a href="#">{{ news.title }}</a></li>
{% endfor %}
-
在info/utils文件夹下建立一个名为common.py文件
##点击排行显示过滤器
def do_index_class(index):
if index == 0:
return "first"
elif index == 1:
return "second"
elif index == 2:
return "third"
else:
return ""
- 在info/init.py文件中添加代码
from info.utils.common import do_index_class
app.add_template_filter(do_index_class,"index_class")
-
运行程序
四、分类展示
- 打开info/modules/index/views.py文件
categories_dicts = []
"""获取新闻分类数据"""
categories = Category.query.all()
for category in categories:
categories_dicts.append(category.to_dict())
data = {
"user_info":user.to_dict() if user else None,
"click_news_list":click_news_list,
"categories":categories_dicts,
}
- 打开info/modules/index/views.py文件
{% for category in data.categories %}
<li class="{% if loop.index0 == 0 %}active"
{% endif %}data-cid="{{ category.id }}">
<a href="javascript:;">{{ category.name }}</a></li>
{% endfor %}
-
运行程序
五、首页新闻
- 打开info/modules/index/views.py文件
@index_blu.route('/newslist')
def get_news_list():
#1.获取参数
args_dict = request.args
#2.第几页
page = args_dict.get('page',1)
#一页有多少数据
per_page = args_dict.get('per_page',constants.HOME_PAGE_MAX_NEWS)
#cid
category_id = args_dict.get('cid',1)
#校验参数
try:
page = int(page)
per_page = int(per_page)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR,errmsg="参数错误")
filter = []
#查询数据并分页
if category_id != "1":
filter.append(News.category_id == category_id)
try:
paginate = News.query.filter(*filter).order_by(News.create_time.desc()).paginate(page,per_page,False)
# 获取查询的数据
items = paginate.items
# h获取总页数
total_page = paginate.pages
current_page = paginate.page
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="数据查询失败")
news_li = []
for news in items:
news_li.append(news.to_basic_dict())
return jsonify(errno=RET.OK, errmsg="OK", totalPage=total_page, currentPage=current_page, newsList=news_li,
cid=category_id)
# 返回数据
- 打开info/static/news/js/index.js文件
var currentCid = 1; // 当前分类 id
var cur_page = 1; // 当前页
var total_page = 1; // 总页数
var house_data_querying = true; // 是否正在向后台获取数据
$(function () {
// 调用updateNewsData方法更新数据
updateNewsData()
// 首页分类切换
$('.menu li').click(function () {
var clickCid = $(this).attr('data-cid')
$('.menu li').each(function () {
$(this).removeClass('active')
})
$(this).addClass('active')
if (clickCid != currentCid) {
// 记录当前分类id
currentCid = clickCid
// 重置分页参数
cur_page = 1
total_page = 1
updateNewsData()
}
})
//页面滚动加载相关
$(window).scroll(function () {
// 浏览器窗口高度
var showHeight = $(window).height();
// 整个网页的高度
var pageHeight = $(document).height();
// 页面可以滚动的距离
var canScrollHeight = pageHeight - showHeight;
// 页面滚动了多少,这个是随着页面滚动实时变化的
var nowScroll = $(document).scrollTop();
if ((canScrollHeight - nowScroll) < 100) {
// TODO 判断页数,去更新新闻数据
if (!house_data_querying){
// 将是否发送数据设置为真
house_data_querying =true;
if(cur_page < total_page){
// 调用updateNewsData方法更新数据
updateNewsData()
}else {
house_data_querying =false;
}
}
}
})
})
function updateNewsData() {
// TODO 更新新闻数据
var params = {
"page": cur_page,
"per_page": 5,
"cid": currentCid
}
$.get("/newslist", params,function (resp) {
// 将 house_data_querying设置为false 以便下次滚动加载
house_data_querying = false;
if (resp){
total_page = resp.totalPage
//清空原来数据
if(cur_page == 1){
$(".list_con").html("")
}
// 每调用一次,要更新cur_page
cur_page += 1
// 显示数据
for (var i=0; i < resp.newsList.length; i++){
var news = resp.newsList[i]
var content = '<li>'
content += '<a href="/news/'+news.id+'" class="news_pic fl"><img src="' + news.index_image_url + '?imageView2/1/w/170/h/170"></a>'
content += '<a href="/news/'+news.id+'" class="news_title fl">' + news.title + '</a>'
content += '<a href="/news/'+news.id+'" class="news_detail fl">' + news.digest + '</a>'
content += '<div class="author_info fl">'
content += '<div class="source fl">来源:' + news.source + '</div>'
content += '<div class="time fl">' + news.create_time + '</div>'
content += '</div>'
content += '</li>'
$(".list_con").append(content)
}
}
})
}
-
打开打开info/templates/news/index.html文件
-
运行程序
可以无限循环
六、完善CSRF
- 打开info/init.py文件
from flask_wtf.csrf import generate_csrf
---
CSRFProtect(app)
---
@app.after_request
def after_request(response):
#调用生成csrf的函数
csrf_token = generate_csrf()
#通过cookie传递给前台
response.set_cookie("csrf_token",csrf_token)
return response
七、详情链接
-
将static文件下面的detail.html文件复制到temlpates文件夹中
-
在modules文件夹下建立一个名字叫news的py文件夹,在文件夹内创建一个views.py文件
- 打开indo/modeules/news/init.py文件
# 创建蓝图
from flask import Blueprint
news_blu = Blueprint('news', __name__,url_prefix='/news')
from . import views
- 打开info/init.py文件
from info.modules.news import news_blu
app.register_blueprint(news_blu)
- 打开info/modules/news/views.py文件
from flask import render_template
from info.modules.news import news_blu
@news_blu.route('/<int:news_id>')
def news_detail(news_id):
return render_template('news/detail.html')
- 打开info/static/news/js/index.js
ontent += '<a href="/news/'+news.id+'" class="news_pic fl"><img src="' + news.index_image_url + '?imageView2/1/w/170/h/170"></a>'
content += '<a href="/news/'+news.id+'" class="news_title fl">' + news.title + '</a>'
content += '<a href="/news/'+news.id+'" class="news_detail fl">' + news.digest + '</a>'
-
打开info/temlates/news/index.html文件
-
刷新页面
点击这三处,都可以实现跳转页面
跳转页面如下:
以上项目可在我的GitHub上面查看:
(此文章仅作为个人学习笔记使用,如有错误欢迎指正~)