Python Flask搭建个人博客详细回顾—(4.1 博客后台管理)

本文围绕基于Flask和Python的个人博客展开,回顾上节内容后,详细介绍文章管理,包括新增、管理、编辑文章及上传图片设置,给出相关代码和操作注意事项,如避免CSRF攻击等。还提及博客设置的简单代码,下节将介绍评论和分类管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

个人博客Demo: link.
GitHub项目完整链接:link


回顾上一节主要讲了以下2个方面内容:

  • 文章详情页面以及评论板块
  • 博客的登录与登出

4.1.1 文章管理

  • 管理界面的快捷入口在导航栏处

1.新增文章

  • new_post.html 代码如下:
{% extends 'base.html' %}
{% from 'bootstrap/form.html' import render_form %}

{% block title %}新建文章{% endblock title %}

{% block content %}
<div class="page-header">
        <h1>新建文章</h1>
</div>
<div>
        {{ render_form(form) }}
</div>
{% endblock content %}

{% block scripts %}
    {{ super() }}
    <script type="text/javascript" src="{{ url_for('static', filename='ckeditor/ckeditor.js')}}"></script>
    {{ ckeditor.config(name='body') }}
{% endblock scripts %}
  • 上面代码中对{% block script %}追加写入了一个js资源文件,ckeditor.js。这个资源文件用于加载富文本编辑器,对于资源文件包括整个static静态文件文件夹建议到我的github仓库上去下载下来:link,也可以去官方网站下载相应资源文件或用CDN载入
  • 新建文章 new_post视图函数代码如下:
    新增导入以下模块
from flask import render_template
from Blog.models import Category
from Blog.forms import PostForm
@admin_bm.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_post():
    form = PostForm()

    if form.validate_on_submit():
        title = form.title.data
        body = form.body.data
        category = Category.query.get(form.category.data)
        post = Post(title=title, body=body, category=category)
        db.session.add(post)
        db.session.commit()
        flash('新文章创建成功!', 'success')
        return redirect(url_for('blog.show_post', post_id=post.id))
    return render_template('admin/new_post.html', form=form)
  • category = Category.query.get(form.category.data)获取category的id值查询到对应分类记录

  1. 管理文章
  • 管理文章页面 manage_post.html代码如下:
{% extends 'base.html' %}
{% from 'bootstrap/pagination.html' import render_pagination %}

{% block title %}文章管理{% endblock title %}

{% block content %}

<div class="page-header">
    <h1>
        <small class="text-muted">文章共计:{{pagination.total}} 篇</small>
        <span class="float-right "><a href="{{ url_for('.new_post')}}" class="btn btn-primary btn-sm">新建</a></span>
    </h1>
</div>
{% if posts %}
<table class="table table-striped">
    <thead>
    <tr>
        <th>No.</th>
        <th>标题</th>
        <th>分类</th>
        <th>日期</th>
        <th>评论</th>
        <th>字数</th>
        <th>操作</th>
    </tr>
    </thead>
    {% for post in posts %}
    <tr>
        <td>{{ loop.index + ((pagination.page - 1) * config.BLOG_MANAGE_POST_PER_PAGE) }}</td>
        <td><a href="{{ url_for('blog.show_post', post_id=post.id)}}" class="text-dark">{{ post.title }}</a></td>
        <td><a href="{{ url_for('blog.show_category', category_id=post.category.id)}}" class="text-dark">
            {{ post.category.name }}</a></td>
        <td>{{ moment(post.timestamp).format('LL')}}</td>
        <td>{{ post.comments|length }}</td>
        <td>{{ post.body|length }}</td>
        <td><a class="btn btn-info btn-sm" href="{{ url_for('.edit_post', post_id=post.id) }}">编辑</a>
            <form class="inline" method="post"
                  action="{{ url_for('.delete_post', post_id=post.id, next=request.full_path)}}">
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
                <button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('你确定删除此篇文章?'); ">
                    删除
                </button>
            </form>
        </td>
    </tr>
    {% endfor %}
</table>
<div class="page-footer">{{ render_pagination(pagination) }}</div>
{% else %}
<div class="tip"><h5>这里一篇文章都没有...</h5></div>
{% endif %}
{% endblock content %}
  • 文章管理主页包含新建文章按钮,主要通过表格进行文章的管理,表格中还包含编辑,删除按钮
  • 删除操作会修改数据库,为避免CSRF攻击,我们使用表单form元素提交POST请求
  • 需要注意的是我们给删除按钮设置一个删除确认弹窗,在< button >标签中添加一个onclick属性,设置一行JS代码:return confirm(),在confirm()参数中传入提示信息作为参数

管理文章页面视图函数manage_post代码:

from flask import request, current_app #新增导入

@admin_bm.route('/post/manage')
@login_required
def manage_post():
    page = request.args.get('page', 1, type=int)
    per_page = current_app.config['BLOG_MANAGE_POST_PER_PAGE']
    pagination = Post.query.order_by(Post.timestamp.desc()).paginate(page, per_page=per_page)
    posts = pagination.items

    return render_template('admin/manage_post.html', pagination=pagination, posts=posts, page=page )

删除文章按钮的视图函数delete_post代码:

@admin_bm.route('post/<int:post_id>/delete', methods=['POST'])
@login_required
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    db.session.delete(post)
    db.session.commit()
    flash('文章已删除.', 'success')
    return redirect_back()

3.编辑文章

  • 编辑文章 edit_post.html 代码:
{% extends 'admin/new_post.html' %}
{% from 'bootstrap/form.html' import render_form %}

{% block title %}编辑文章{% endblock title %}
{% block content %}
<div class="page-header">
    <h1>编辑文章</h1>
</div>
{{ render_form(form) }}
{% endblock content%}
  • 编辑文章按钮 edit_post 视图函数代码:
@admin_bm.route('/post/<int:post_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_post(post_id):
    form = PostForm()
    post = Post.query.get_or_404(post_id)

    if form.validate_on_submit():
        post.title = form.title.data
        post.category = Category.query.get(form.category.data)
        post.body = form.body.data
        db.session.commit()
        flash('文章已更新!', 'success')
        return redirect(url_for('blog.show_post', post_id=post.id))

    form.title.data = post.title
    form.category.data = post.category_id
    form.body.data = post.body

    return render_template('admin/edit_post.html', form=form)
  • form .title.data = post.title等类似操作是将数据库中原有的该条记录预放置到form表单输入字段,方便编辑修改

4.上传图片设置

  • 在admin.py中添加以下视图函数: 用于从本地上传图片到服务器
# 新增导入模块
import os
from Blog.helpers import  allowed_file
from flask import send_from_directory
from flask_ckeditor import upload_success, upload_fail


# 获取图片路径
@admin_bm.route('/uploads/<path:filename>')
def get_image(filename):
    return send_from_directory(current_app.config['MYBLOG_UPLOAD_PATH'], filename)


# 上传图片
@admin_bm.route('/upload', methods=['POST'])
def upload_image():
    # 创建uploads文件夹用于上传图片
    folder = os.path.exists(current_app.config['MYBLOG_UPLOAD_PATH'])
    if not folder:
            os.makedirs(current_app.config['MYBLOG_UPLOAD_PATH'])
    # 获取上传对象
    f = request.files.get('upload')
    # 若不符合规定文件名
    if not allowed_file(f.filename):
        return upload_fail('Image only!')
    f.save(os.path.join(current_app.config['MYBLOG_UPLOAD_PATH'], f.filename))
    # 设置图片url规则
    url = url_for('.get_image', filename=f.filename)
    return upload_success(url, f.filename)

4.1.2 博客设置

  • 博客设置的代码相当简单
  • 博客设置settings.html 代码如下:
{% extends 'base.html' %}
{% from 'bootstrap/form.html' import render_form %}

{% block title %}设置{% endblock title%}

{% block content %}
    <div class="page-header">
        <h1>设置</h1>
    </div>
    <div>
        {{ render_form(form) }}
    </div>
{% endblock content %}
  • 博客设置settings视图函数代码如下:
# 新增导入模块
from Blog.forms import SettingForm
from flask_login import  current_user

@admin_bm.route('/setting', methods=['GET', 'POST'])
@login_required
def settings():
    form = SettingForm()

    # if和下面代码的顺序不能变
    if form.validate_on_submit():
        current_user.blog_title = form.blog_title.data
        current_user.name = form.name.data
        current_user.about = form.about.data
        db.session.commit()
        flash('博客设置已更新!', 'success')
        return redirect(url_for('blog.index'))

    form.blog_title.data = current_user.blog_title
    form.name.data = current_user.name
    form.about.data = current_user.about

    return render_template('admin/settings.html', form=form)

下一节将介绍评论管理以及分类管理的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值