用 Python + Flask + Tailwind极速搭建高颜值个人博客

用 Python + Flask + Tailwind极速搭建高颜值个人博客

告别臃肿!用 Python + Flask + Tailwind极速搭建高颜值个人博客(附完整源码)

在这里插入图片描述
在这里插入图片描述

前言:为什么选择 Flask?

之前写个人网站或是小型的 Web 项目,总习惯操起老本行,用 PHP 配合原生 JavaScript 吭哧吭哧地写后端逻辑和前端页面。虽然跑得通,但随着时代发展,总感觉那种前后端高度耦合的开发模式不够优雅。

最近打算重新搭建一个个人博客,索性抛开繁重的全栈包袱,尝试了 Python 著名的微框架 Flask,并配合目前前端最火的 Tailwind CSS。不夸张地说,开发体验直接拉满!

如果你也想拥有一个完全属于自己的高颜值博客,但又不想被庞大的框架(比如 Django 或者传统的 WordPress)束缚,这篇教程将带你用不到 200 行代码,从零起飞。


一、 技术栈解析

我们的核心诉求是:轻量、好看、不用写繁琐的 SQL、不用碰头疼的 CSS

  • 后端引擎:Flask。小巧灵活,路由机制极其直观,非常适合用来写博客这种轻量级应用。
  • 数据库:SQLite + SQLAlchemy。直接将数据库集成在本地文件中,并使用 ORM(对象关系映射)操作数据,告别手写 SQL 的痛苦。
  • 前端 UI:Tailwind CSS (CDN)。原子化 CSS 框架,直接在 HTML 标签里写类名就能实现极其现代、美观的卡片式和响应式布局。

二、 极速环境搭建

首先,新建一个项目文件夹,建议使用 Python 虚拟环境来隔离依赖:

# 创建并激活虚拟环境 (Windows) python -m venv .venv .venv\Scripts\activate # 安装核心依赖包 pip install Flask Flask-SQLAlchemy 

三、 核心代码实现

整个项目只需要 1 个 Python 后端文件和 4 个 HTML 前端模板。项目结构如下:

flask_blog/ │-- app.py # 后端核心逻辑与数据库模型 └── templates/ # HTML 模板文件夹 ├── base.html # 全局基础母版(包含导航栏) ├── index.html # 首页(文章列表展示) ├── post.html # 文章详情页 └── create.html # 发布文章页 

1. 后端大脑:app.py

在这里,我们定义了文章的数据库模型(Article),并写好了首页展示、文章详情和发布文章的三个核心路由。首次运行会自动创建 blog.db 数据库。

from flask import Flask, render_template, request, redirect, url_for, flash from flask_sqlalchemy import SQLAlchemy from datetime import datetime app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///blog.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False app.config['SECRET_KEY']='dev_key_123' db = SQLAlchemy(app)# 1. 数据库模型:文章表classArticle(db.Model):id= db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) content = db.Column(db.Text, nullable=False) created_at = db.Column(db.DateTime, default=datetime.now)with app.app_context(): db.create_all()# 2. 路由:首页文章列表@app.route('/')defindex(): articles = Article.query.order_by(Article.created_at.desc()).all()return render_template('index.html', articles=articles)# 3. 路由:文章详情页@app.route('/post/<int:article_id>')defpost(article_id): article = Article.query.get_or_404(article_id)return render_template('post.html', article=article)# 4. 路由:写文章@app.route('/create', methods=['GET','POST'])defcreate():if request.method =='POST': title = request.form['title'] content = request.form['content']ifnot title ornot content: flash('标题和内容不能为空!')else: new_article = Article(title=title, content=content) db.session.add(new_article) db.session.commit()return redirect(url_for('index'))return render_template('create.html')if __name__ =='__main__': app.run(debug=True)

2. 前端骨架:templates/base.html

我们通过 CDN 引入了 Tailwind CSS,并利用 Jinja2 的模板继承 {% block content %} 避免了重复写导航栏代码。

<!DOCTYPEhtml><htmllang="zh"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>{% block title %}Code&Life 博客{% endblock %}</title><scriptsrc="https://cdn.tailwindcss.com"></script><scriptsrc="https://cdn.tailwindcss.com?plugins=typography"></script></head><bodyclass="bg-gray-50 text-gray-800 font-sans flex flex-col min-h-screen"><navclass="bg-white shadow-sm border-b border-gray-100"><divclass="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8"><divclass="flex justify-between h-16 items-center"><ahref="{{ url_for('index') }}"class="text-xl font-bold text-indigo-600">Code&Life</a><divclass="space-x-4"><ahref="{{ url_for('index') }}"class="text-gray-500 hover:text-indigo-600 font-medium transition">首页</a><ahref="{{ url_for('create') }}"class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition shadow-sm font-medium">写文章</a></div></div></div></nav><mainclass="flex-grow max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8 w-full"> {% block content %}{% endblock %} </main><footerclass="bg-white border-t border-gray-200 mt-auto"><divclass="max-w-5xl mx-auto px-4 py-6 text-center text-sm text-gray-400">&copy; 2026 My Personal Blog. Built with Flask & Tailwind. </div></footer></body></html>

3. 页面渲染(首页、详情、发布)

(作者注:在 templates 文件夹下创建以下三个文件,代码详见文末源码库或参照完整功能。为节省篇幅,这里重点展示布局思路)

  • index.html:使用 Grid 网格布局,将后端传来的 articles 对象循环渲染成漂亮的卡片。
  • post.html:利用 Tailwind 的 prose 插件,自动优化长文本的行距和排版,让阅读体验极佳。
  • create.html:纯净的表单提交页面,通过 POST 请求将数据发回后端。

四、 运行测试与总结

在终端执行:

python app.py 

打开 http://127.0.0.1:5000,你就能看到一个完全由你掌控的现代风博客系统了!

整个开发过程行云流水,Flask 帮我们搞定了 HTTP 请求和路由分发,SQLAlchemy 让我们彻底抛弃了 SQL 字符串拼接,而 Tailwind CSS 则让我们免去了在不同 CSS 文件中来回切换的折磨。

进阶预告:
目前的博客虽然好看,但还不支持开发者刚需的 Markdown 语法。下一篇文章,我将分享如何在这个项目基础上,一键接入 Markdown 解析引擎,并实现炫酷的代码高亮功能。敬请期待!

全部源码点击下载


欢迎在评论区交流你在搭建过程中遇到的坑,或者分享你的博客链接!

Read more

惊叹数据结构之美,品味排序算法之妙:对计排、桶排的详细介绍

惊叹数据结构之美,品味排序算法之妙:对计排、桶排的详细介绍

大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在ZEEKLOG这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 * 引言 * 正文 * 一、计数排序(Counting Sort) * 二、基数排序(Radix Sort) * 三、总结 * 快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!! 引言 排序算法中的基数排序和计数排序都是非基于传统比较的排序方法,它们各自有着独特的实现原理和应用场景。下面小编将从代码实现的角度对这两种排序算法进行详细介绍。 那接下来就让我们开始遨游在知识的海洋! 正文 一、计数排序(Counting Sort) 原理概述: 计数排序是一种适用于元素范围较小的排序算法。它利用一个额外的计数数组来记录待排序数组中每个元素出现的次数,然后根据这些次数来确定每个元素在最终排序数组中的位置。 代码实现步骤: 1. 确定元素范围:找出待排序数组中的最小值和最大值,记为min和max。2. 创建计数数组:创建

By Ne0inhk
每日精讲:环形链表、两个数组中的交集、随机链表的复制

每日精讲:环形链表、两个数组中的交集、随机链表的复制

Hello大家好! 很高兴与大家见面! 给生活添点快乐,开始今天的编程之路。 我的博客:<但愿. 我的专栏:C语言、题目精讲、算法与数据结构、C++ 欢迎点赞,关注 一 环形链表 1.1题目链接:环形链表II 1.2题目描述: 给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。注意不允许修改 链表。

By Ne0inhk
《算法题讲解指南:优选算法-位运算》--33.判断字符是否唯一,34.丢失的数字

《算法题讲解指南:优选算法-位运算》--33.判断字符是否唯一,34.丢失的数字

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》 《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心 ✨未择之路,不须回头 已择之路,纵是荆棘遍野,亦作花海遨游 目录 位运算基础前置知识: 位1的个数 比特位计数 汉明距离 只出现一次的数字 只出现一次的数字||| 34. 判断字符是否唯一 题目链接: 题目描述: 题目示例: 解法(位图的思想): 算法思路: C++算法代码: 算法总结及流程解析: 35. 丢失的数字 题目链接: 题目描述: 题目示例: 解法(位运算): 算法思路: C++算法代码: 算法总结及流程解析: 结束语 位运算基础前置知识:       回顾了上面位运算基础前置的知识这里有五道非常简单的题可以试试手,都是考察位运算的题目: 位1的个数 191.

By Ne0inhk
【数据结构】宜宾大学-计院-实验五

【数据结构】宜宾大学-计院-实验五

实验五 栈和队列(队列的基本操作) * 实验目的: * 链表结点结构: * 实验结果: * 运行截图: * 代码实现: 实验目的: 1.掌握队列的顺序存储结构和链式存储结构 2.实现队列的基本操作,包括队列的建立、入队列、出队列、判断队列是否空等 实验内容: 1.完成链队列的建立 2.实现链队列的入队操作 3.实现链队列的出队列操作 4.实现判断链队列是否为空 5.实现销毁链队列 6.自己设计一组数据,模拟入队列,出队列 链表结点结构: typedef struct QNode { int data; struct QNode *Next; }QNode,*QueuePtr; 队列结构: struct { QueuePtr front; QueuePtr rear; }Ptr;

By Ne0inhk