前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flask框架之博客的发布和编辑

Flask框架之博客的发布和编辑

作者头像
码农飞哥
发布2021-08-18 11:16:55
2930
发布2021-08-18 11:16:55
举报
文章被收录于专栏:好好学习

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

  • 关于session的设置
  • 用户登录
  • 在其他视图中验证
  • 博客蓝图设置
    • 首页
  • 发布文章
    • 文章修改接口
  • 运行效果图
    • 登录前
    • 登录后
  • 总结

关于session的设置

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

代码语言:javascript
复制
Flask-Session==0.3.2

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

代码语言:javascript
复制
from flask_session import Session
  #  设置Session
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = os.urandom(24)
Session(app)

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

用户登录

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

代码语言:javascript
复制
  # 清除session
 session.clear()
 session['user_id'] = user.get_id()

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

代码语言:javascript
复制
@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)

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

在其他视图中验证

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

代码语言:javascript
复制
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

博客蓝图设置

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

代码语言:javascript
复制
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__)

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

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

首页

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

代码语言:javascript
复制
@bp.route('/')
def index():
    posts = blog_service.get_last_blog()
    return render_template('blog/index.html', posts=posts)

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

代码语言:javascript
复制
<!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>

发布文章

代码语言:javascript
复制
@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')

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

代码语言:javascript
复制
 <!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>

文章修改接口

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

代码语言:javascript
复制
@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)

对应的页面是blog/update.html

代码语言:javascript
复制
<!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>

运行效果图

登录前

在这里插入图片描述

登录后

在这里插入图片描述

总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农飞哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于session的设置
  • 用户登录
  • 在其他视图中验证
  • 博客蓝图设置
    • 首页
    • 发布文章
      • 文章修改接口
      • 运行效果图
        • 登录前
          • 登录后
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档