Python博客项目搭建之博客蓝图和视图

举报
码农飞哥 发表于 2021/05/29 12:39:41 2021/05/29
【摘要】 您好,我是码农飞哥,感谢您阅读本文!上一篇文章我们介绍了一分钟快速实现Flask框架的蓝图和视图,这一篇文章我们将接着介绍博客的发布以及编辑。同样是运用视图和蓝图。 文章目录 关于session的设置用户登录在其他视图中验证博客蓝图设置首页 发布文章文章修改接口 运行效果图登录前登录后 总结 关于session的设置 首先需要引入Flask-Ses...

您好,我是码农飞哥,感谢您阅读本文!上一篇文章我们介绍了一分钟快速实现Flask框架的蓝图和视图,这一篇文章我们将接着介绍博客的发布以及编辑。同样是运用视图和蓝图。

关于session的设置

首先需要引入Flask-Session的库。

Flask-Session==0.3.2

  
 
  • 1

这里是将Session保存到本地。所以,我们需要实例化app时,设置session,代码地址在:flaskr/__init__.py

from flask_session import Session
  #  设置Session
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = os.urandom(24)
Session(app)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

当我们向Session中设置数据时,Flask框架会在项目目录下创建如下文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bdSlb0va-1610945986545)(./images/1610935419384.png)]。

用户登录

用户登录之后,在登录接口将用户ID放入session中。代码地址是:flaskr/views/auth.py,设置的代码如下:

	 # 清除session
	session.clear()
	session['user_id'] = user.get_id()

  
 
  • 1
  • 2
  • 3

现在用户ID被设置到了sesssion中,可以被后续的请求使用。在每个请求的开头,如果用户已登录,那么其用户信息应当被载入,以使其可用于其他视图。代码地址是:flaskr/views/auth.py

@bp.before_app_request
def load_logged_in_user(): user_id = session.get('user_id') if user_id is None: g.user = None else: g.user = user_service.query_user_by_id(user_id)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

bp.before_app_request() 注册一个在视图函数之前运行的函数,无论其URL是什么,load_logged_in_user检查用户id是否已经储存在session中,并从数据库中获取用户数据,然后储存在g.user中。g.user的持续时间比请求时间要长,如果没有用户id,或者id不存在,那么g.user将会是None。

在其他视图中验证

装饰器返回一个新的视图,该视图包含了传递给装饰器的原视图,新的函数会检查用户是否已经载入,如果已载入,那么就继续正常执行原视图,否则就重定向到登录页面。

def login_required(view): @functools.wraps(view) def wrapped_view(**kwargs): if g.user is None: return redirect(url_for('auth.login')) return view(**kwargs) return wrapped_view

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

博客蓝图设置

前面我们已经设置好了用户的session信息,接下来就是在博客首页中使用了,博客内容的模块,我们新增了一个蓝图。这里我们创建了blog.py文件,这里的blog蓝图没有指定url_prefix。地址是:flaskr/views/blog.py

from flask import ( Blueprint, flash, g, redirect, render_template, request, url_for
)
from werkzeug.exceptions import abort
from flaskr.views.auth import login_required
from flaskr.biz import blog_service

bp = Blueprint('blog', __name__)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

接着将该蓝图注册到app中。flaskr/_init_.py

def create_app():
	.....省略其余代码
	from flaskr.views import blog app.register_blueprint(blog.bp)
	return app

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

首页

flaskr/views/blog.py,这里指定博客的首页为经常访问的页面,所以地址指定/

@bp.route('/')
def index(): posts = blog_service.get_last_blog() return render_template('blog/index.html', posts=posts)

  
 
  • 1
  • 2
  • 3
  • 4

这里将博客的相关Html文件放在一个单独的目录blog下。blog/index.html

<!DOCTYPE html>
{% extends 'base.html' %}

{% block header %}
<h1>{% block title %}Posts{% endblock %}</h1>
{% if g.user %}
<a class="action" href="{{ url_for('blog.create') }}">New</a>
{% endif %}
{% endblock %}

{% block content %}
{% for post in posts %}
<article class="post"> <header> <div> <h1>{{post['title']}}</h1> <div class="about"> by {{ post['username'] }} on{{ post['created'].strftime('%Y-%m-%d') }}</div> </div> {% if g.user['id']==post['author_id'] %} <a class="action" href="{{ url_for('blog.update',id=post['id']) }}">编辑博客</a> {% endif %} </header> <p class="body">{{ post['body'] }}</p>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

发布文章

@bp.route('/create', methods=('GET', 'POST'))
@login_required
def create(): if request.method == 'POST': title = request.form['title'] body = request.form['body'] error = None if not title: error = 'Title is required' if error is not None: flash(error) else: blog_service.insert_post(title, body, g.user.get_id()) return redirect(url_for('blog.index')) return render_template('blog/create.html')

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

发布文章传入title以及body。首先会校验这两参数是否为空,如果都不为空的话,则将文章数据保存到blog表中。
对应的页面是blog/create.html

	<!DOCTYPE html>
	{% extends 'base.html' %}
	{% block header %}
	<hl>{% block title %}发布文章{% endblock %}</hl>
	{% endblock %}
	{% block content %}
	<form method="post">
		<label for="title">文章标题</label>
		<input name="title" id="title" value="{{ request.form['title'] }}" required>
		<label for="body">文章体</label>
		<textarea name="body" id="body">{{ request.form['body'] }}</textarea>
		<input type="submit" value="Save">
	</form>
	{% endblock %}
	</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

文章修改接口

文章修改接口,首先是根据id查询文章,如果文章不为空则进行修改。

@bp.route('/<int:id>/update', methods=['GET', 'POST'])
@login_required
def update(id): post = get_post(id) if request.method == 'POST': title = request.form['title'] body = request.form['body'] error = None if not title: error = 'Title is required' if error is not None: flash(error) else: blog_service.update_post(title, body, id) return redirect(url_for('blog.index')) return render_template('blog/update.html', post=post)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

对应的页面是blog/update.html

<!DOCTYPE html>
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}编辑 "{{ post['title'] }}"{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post"> <label for="title">标题</label> <input name="title" id="title" value="{{ request.form['title'] or post['title'] }}" required> <label for="body">文章体</label> <textarea name="body" id="body">{{ request.form['body'] or post['body'] }}</textarea> <input type="submit" value="保存">
</form>
<form action="{{ url_for('blog.delete',id=post['id']) }}" method="post"> <input class="danger" type="submit" value="Delete" onclick="return confirm('Are you sure?');">
</form>
{% endblock %}
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

运行效果图

登录前

在这里插入图片描述

登录后

在这里插入图片描述

总结

本文详细介绍了,博客系统的首页代码实现,代码相对比较简单。

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/112774208

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。