用 Flask 来写个轻博客 (30) — 使用 Flask-Admin 增强文章管理功能

Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog

目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目
用 Flask 来写个轻博客 (2) — Hello World!
用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy
用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览
用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法
用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数
用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单
用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图
用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目
用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象
用 Flask 来写个轻博客 (19) — 以 Bcrypt 密文存储账户信息与实现用户登陆表单
用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码
用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录
用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面
用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录
用 Flask 来写个轻博客 (24) — 使用 Flask-Login 来保护应用安全
用 Flask 来写个轻博客 (25) — 使用 Flask-Principal 实现角色权限功能
用 Flask 来写个轻博客 (26) — 使用 Flask-Celery-Helper 实现异步任务
用 Flask 来写个轻博客 (27) — 使用 Flask-Cache 实现网页缓存加速
用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy

扩展阅读

Flask项目集成富文本编辑器CKeditor

实现文章管理功能

该功能是在 ModelView 提供 CRUD 管理的基础上实现, 但是仍然存在一个问题, 就是 Flask-Admin 默认使用的文本编辑字段为 textarea, 这无法满足博客文章的样式需求. 所以我们这次来看看怎样替换一个默认的字段类型.

  • 创建一个新的字段类型
    vim jmilkfansblog/forms.py
from wtforms import (
    widgets,
    StringField,
    TextField,
    TextAreaField,
    PasswordField,
    BooleanField,
    ValidationError
)


class CKTextAreaField(TextAreaField):
    """Create a new Field type."""

    # Add a new widget `CKTextAreaField` inherit from TextAreaField.
    widget = CKTextAreaWidget()


class CKTextAreaWidget(widgets.TextArea):
    """CKeditor form for Flask-Admin."""

    def __call__(self, field, **kwargs):
        """Define callable type(class)."""

        # Add a new class property ckeditor: `<input class=ckeditor ...>`
        kwargs.setdefault('class_', 'ckeditor')
        return super(CKTextAreaWidget, self).__call__(field, **kwargs)

NOTE 1: 新建的 CKTextAreaField 字段类型继承了 TextAreaField, 唯一的区别在于, CKTextAreaField 增加了一个 widget 的小部件, widget 的意义在于为该字段的 HTML 标签增加一个 class EG. <input class=ckedior ...>.

NOTE 2: widget 是由 class CKTestAreaWidget 返回的, 该类作为的唯一一件事情就是将 HTML 标签中的 class 的值设定为 ckedior, EG. <textarea name="editor" id="editor" class="ckeditor" rows="10" cols="80"> 这样的话, Ckeditor 就会将原默认的 TextArea(editor) 给替换掉.

  • 定义一个 PostView 类
    vim jmilkfansblog/controllers/admin.py
class PostView(CustomModelView):
    """View function of Flask-Admin for Post create/edit Page includedin Models page"""

    # Using the CKTextAreaField to replace the Field name is `test`
    form_overrides = dict(text=CKTextAreaField)

    # Using Search box
    column_searchable_list = ('text', 'title')

    # Using Add Filter box
    column_filters = ('publish_date',)

    # Custom the template for PostView
    # Using js Editor of CKeditor
    create_template = 'admin/post_edit.html'
    edit_template = 'admin/post_edit.html'

NOTE 1: form_overrides 指定使用新的字段类型 CKTextAreaField 替换原来的 TextAreaField.

NOTE 2: column_searchable_list 指定一个搜索框, 和搜索的范围为 post.text/post.title

NOTE 3: column_filters 指定一个过滤器, 筛选更加精确的值

NOTE 4: create_template/edit_template 指定自定义模板文件

  • 创建自定义模板
    vim jmilkfansblog/templates/admin/post_edit.html
{% extends 'admin/model/edit.html' %}

{% block tail %}
{{ super() }}
<script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
{% endblock %}

NOTE 1: 该自定义模板继承了 admin/model/edit.html, 但却替换了
{% block tail %} 为一个 CKEditor.

实现效果

  • 文章列表
    这里写图片描述

  • 创建/编辑文章
    这里写图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
可以参考以下代码: ```python from flask import Flask, redirect, url_for from flask_admin import Admin, AdminIndexView from flask_admin.contrib.sqla import ModelView from flask_login import current_user, LoginManager, login_user, UserMixin, logout_user app = Flask(__name__) app.config['SECRET_KEY'] = 'secret_key' login_manager = LoginManager() login_manager.init_app(app) # 定义一个 User 类,用于记录用户信息 class User(UserMixin): def __init__(self, user_id): self.id = user_id # 登录视图,处理用户登录请求 @app.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('admin.index')) # 处理用户提交的表单 if request.method == 'POST': user_id = request.form['user_id'] password = request.form['password'] # 验证用户身份 if user_id == 'admin' and password == 'password': user = User(user_id) login_user(user) return redirect(url_for('admin.index')) # 显示登录表单 return render_template('login.html') # 登出视图,处理用户登出请求 @app.route('/logout') def logout(): logout_user() return redirect(url_for('login')) # 继承 AdminIndexView,实现自定义首页 class MyAdminIndexView(AdminIndexView): def is_accessible(self): return current_user.is_authenticated def inaccessible_callback(self, name, **kwargs): return redirect(url_for('login')) # 定义一个简单的数据模型 class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), nullable=False) email = db.Column(db.String(120), nullable=False, unique=True) # 继承 ModelView,实现 CRUD 页面 class UserView(ModelView): column_searchable_list = ['username', 'email'] column_filters = ['username', 'email'] column_editable_list = ['username', 'email'] column_sortable_list = ['username', 'email'] # 创建 Admin 实例,注册模型视图 admin = Admin(app, index_view=MyAdminIndexView()) admin.add_view(UserView(User, db.session)) if __name__ == '__main__': app.run(debug=True) ``` 以上代码实现了一个简单的登录界面和一个数据管理页面,用户可以使用账号密码登录来访问数据管理页面。需要注意的是,这里使用Flask-Login 扩展管理用户信息,使用 Flask-Admin 扩展来实现数据管理页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

范桂飓

文章对您有帮助就请一键三连:)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值