通过 Flask 的轻量生态 —— Flask-Admin + Flask-Login + SQLAlchemy 。在短短几百行代码内快速构建一个可登录、可视化、可管理的数据后台。
案例项目:《行迹管理平台》

引言:为什么选择 Flask-Admin 架构?
在传统的后台开发方式中,我们往往要自行编写数据管理的前端页面,实现分页、搜索、表单验证,再做一套登录权限系统,最后才能看到一点可视化结果。
对于中小型项目、原型验证或内部工具来说,这样的投入显然过重。而 Flask 的生态非常“轻”,它的核心是只用需要的部分。它不像 Django 那样自带一整套庞大的后台系统,
而是通过高度模块化的扩展机制,让你按需组合。于是,就诞生了这样的“后台三件套”的组合:
| 模块名称 |
功能描述 |
| Flask-Admin |
零前端代码生成后台页面,支持模型可视化编辑 |
| Flask-Login |
轻量的用户登录与会话管理 |
| SQLAlchemy |
主流 ORM 框架,查询简洁可扩展 |
项目结构设计

数据库使用 PostgreSQL,模板引擎为 Jinja2,图表由 ECharts 驱动。
Flask-Login:轻量认证体系
用户认证由 LoginManager 管理:
1 2 3 4 5 6
| login_manager = LoginManager(app)
@login_manager.user_loader def load_user(id): return db.session.get(AdminUser, int(id))
|
在 /login 路由中进行用户名与密码校验:
1 2 3 4 5 6 7 8 9 10 11
| @app.route('/login', methods=['post']) def login(): username = request.form.get('username') password = request.form.get('password') user = AdminUser.query.filter_by(username=username).first() if user and user.password == password: login_user(user) return redirect('/') else: return render_template('login.html', error='用户名或密码错误!')
|
Flask-Admin:无需前端的后台管理
在 app.py 中注册 Flask-Admin 并绑定模型视图:
1 2 3 4 5 6 7
| admin = Admin(app, name='行迹管理系统', template_mode='bootstrap4', index_view=MyAdminIndexView(name='首页'))
admin.add_view(UserView(User, db.session, name='用户')) admin.add_view(TrackView(Track, db.session, name='行迹')) admin.add_view(TrackCommentView(TrackComment, db.session, name='评论')) admin.add_view(TrackLikeView(TrackLike, db.session, name='点赞'))
|
以 TrackView 为例:
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 31 32 33 34
| class TrackView(LoginRequiredView): page_size = 10 can_delete = True column_default_sort = ('create_time', True) column_list = ['id', 'title', 'description', 'create_time', 'is_public', 'city', 'state'] column_labels = dict( id='ID', title='标题', description='描述', create_time='创建时间', is_public='权限', city='城市', state='状态' ) column_formatters = { 'create_time': lambda v, c, m, p: m.create_time.strftime('%Y-%m-%d %H:%M:%S'), 'title': lambda v, c, m, p: Markup( f'<div style="max-width: 200px; word-break: break-all;">{m.title}</div>' ), 'description': lambda v, c, m, p: Markup( f'<div style="max-width: 300px; word-break: break-all;">{m.description}</div>' ) } column_choices = { 'is_public': [ (0, '私密'), (1, '公开'), ], 'state': [ (0, '正常'), (1, '禁用'), ] }
|
Flask-Admin 自动渲染表格、分页、搜索、表单等界面。无需编写前端代码,即可完成 CRUD 管理。

ECharts + 高德地图:可视化数据总览


数据统计逻辑(SQLAlchemy 实现)
在 data_stat.py 中,借助 SQLAlchemy 的 func.date() 实现每日新增统计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from sqlalchemy import func, text
def get_new_users_last_7_days(): today = datetime.now() - timedelta(days=1) start_date = today - timedelta(days=7) results = ( db.session.query( func.date(User.create_time).label('date'), func.count(User.id).label('new_users') ) .filter(User.create_time >= start_date) .group_by(func.date(User.create_time)) .order_by(func.date(User.create_time)) .all() ) daily_new_users = {result.date.strftime('%m.%d'): result.new_users for result in results} last_7_days = [(today - timedelta(days=i)).strftime('%m.%d') for i in range(7)] daily_new_users_count = {day: daily_new_users.get(day, 0) for day in last_7_days} dates = list(daily_new_users_count.keys()) new_users_counts = list(daily_new_users_count.values()) return json.dumps(dates), json.dumps(new_users_counts)
|