Python博客项目搭建之博客蓝图和视图
您好,我是码农飞哥,感谢您阅读本文!上一篇文章我们介绍了一分钟快速实现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
- 点赞
- 收藏
- 关注作者
评论(0)