当前位置: 首页 > news >正文

19.Python实战:实现对博客文章的点赞系统

Flask博客点赞系统

一个基于Flask的简单博客系统,具有文章展示和点赞功能。系统使用MySQL存储数据,支持文章展示、点赞/取消点赞等功能。

功能特点

  • 文章列表展示
  • 文章详情查看(模态框展示)
  • 点赞/取消点赞功能(每个IP只能点赞一次)
  • 响应式设计,支持移动端
  • 优雅的动画效果
  • 实时点赞数更新

技术栈

  • 后端:Flask
  • 数据库:MySQL
  • 前端:
    • Bootstrap 5
    • jQuery
    • Font Awesome 5 (心形图标)

系统要求

  • Python 3.6+
  • MySQL 5.7+

项目结构

├── README.md
├── requirements.txt
├── schema.sql
├── app.py
├── insert_test_data.py
└── templates/└── index.html

安装步骤

  1. 克隆项目到本地
  2. 安装依赖包
pip install -r requirements.txt
  1. 创建数据库和表
CREATE DATABASE blog_db;
USE blog_db;

运行schema.sql中的建表语句

source schema.sql;
  1. 修改数据库配置
    app.py中修改数据库连接信息:
db_config = {'host': 'your_host','port': your_port,'user': 'your_username','password': 'your_password','database': 'blog_db'
}
  1. 插入测试数据
python insert_test_data.py
  1. 运行应用
python app.py  

访问 http://localhost:5000 即可看到效果

文件说明

  • app.py: 主应用文件,包含所有路由和业务逻辑
  • schema.sql: 数据库表结构
  • requirements.txt: 项目依赖
  • insert_test_data.py: 测试数据生成脚本
  • templates/index.html: 前端模板文件

数据库设计

articles表

  • id: 文章ID
  • title: 文章标题
  • content: 文章内容
  • author: 作者
  • publish_time: 发布时间
  • likes: 点赞数

user_likes表

  • id: 记录ID
  • article_id: 文章ID(外键)
  • user_ip: 用户IP
  • created_at: 点赞时间

API接口

获取文章列表

  • 路由:GET /
  • 返回:渲染后的文章列表页面

获取文章内容

  • 路由:GET /article/<article_id>
  • 返回:文章内容的JSON数据

点赞/取消点赞

  • 路由:POST /like/<article_id>
  • 返回:更新后的点赞数和操作状态的JSON数据

注意事项

  1. 确保MySQL服务已启动
  2. 检查数据库连接配置是否正确
  3. 确保所需端口未被占用
  4. 建议在虚拟环境中运行项目

可能的改进方向

  1. 添加用户认证系统
  2. 实现文章评论功能
  3. 添加文章分类和标签
  4. 实现文章搜索功能
  5. 添加管理后台
  6. 优化移动端体验
  7. 添加文章分享功能

1.requirements.txt

flask==2.0.1
mysql-connector-python==8.0.26

2.schema.sql

CREATE DATABASE blog_db;
USE blog_db;
CREATE TABLE IF NOT EXISTS articles (id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(200) NOT NULL,content TEXT NOT NULL,author VARCHAR(100) NOT NULL,publish_time DATETIME NOT NULL,likes INT DEFAULT 0
);CREATE TABLE IF NOT EXISTS user_likes (id INT AUTO_INCREMENT PRIMARY KEY,article_id INT NOT NULL,user_ip VARCHAR(50) NOT NULL,created_at DATETIME NOT NULL,UNIQUE KEY unique_like (article_id, user_ip),FOREIGN KEY (article_id) REFERENCES articles(id)
);

3.dianzan.py

from flask import Flask, render_template, jsonify, request
import mysql.connector
from datetime import datetimeapp = Flask(__name__)数据库配置
db_config = {'host': 'localhost','port': 'port','user': 'your_username','password': 'your_password','database': 'blog_db'
}def get_db():return mysql.connector.connect(**db_config)@app.route('/')
def index():conn = get_db()cursor = conn.cursor(dictionary=True)# 获取用户IPuser_ip = request.remote_addr# 获取文章列表和用户点赞状态cursor.execute("""SELECT a.*, CASE WHEN ul.id IS NOT NULL THEN 1 ELSE 0 END as user_likedFROM articles aLEFT JOIN user_likes ul ON a.id = ul.article_id AND ul.user_ip = %sORDER BY a.publish_time DESC""", (user_ip,))articles = cursor.fetchall()cursor.close()conn.close()return render_template('index.html', articles=articles)@app.route('/article/<int:article_id>')
def get_article(article_id):conn = get_db()cursor = conn.cursor(dictionary=True)cursor.execute("SELECT content FROM articles WHERE id = %s", (article_id,))article = cursor.fetchone()cursor.close()conn.close()if article is None:return jsonify({'error': 'Article not found'}), 404return jsonify({'content': article['content']})@app.route('/like/<int:article_id>', methods=['POST'])
def like_article(article_id):conn = get_db()cursor = conn.cursor()user_ip = request.remote_addrtry:# 检查是否已经点赞cursor.execute("""SELECT id FROM user_likes WHERE article_id = %s AND user_ip = %s""", (article_id, user_ip))existing_like = cursor.fetchone()if existing_like:# 如果已经点赞,则取消点赞cursor.execute("""DELETE FROM user_likes WHERE article_id = %s AND user_ip = %s""", (article_id, user_ip))cursor.execute("""UPDATE articles SET likes = likes - 1 WHERE id = %s""", (article_id,))action = 'unliked'else:# 如果未点赞,则添加点赞cursor.execute("""INSERT INTO user_likes (article_id, user_ip, created_at) VALUES (%s, %s, %s)""", (article_id, user_ip, datetime.now()))cursor.execute("""UPDATE articles SET likes = likes + 1 WHERE id = %s""", (article_id,))action = 'liked'conn.commit()# 获取最新点赞数cursor.execute("SELECT likes FROM articles WHERE id = %s", (article_id,))likes = cursor.fetchone()[0]cursor.close()conn.close()return jsonify({'likes': likes, 'action': action})except mysql.connector.Error as err:conn.rollback()cursor.close()conn.close()return jsonify({'error': str(err)}), 500# 添加一个用于插入测试数据的辅助函数
def add_test_article(title, content, author):conn = get_db()cursor = conn.cursor()cursor.execute("INSERT INTO articles (title, content, author, publish_time, likes) VALUES (%s, %s, %s, %s, %s)",(title, content, author, datetime.now(), 0))conn.commit()cursor.close()conn.close()if __name__ == '__main__':app.run(debug=True)

4.insert_test_data.py

from app import get_db
from datetime import datetime, timedeltadef insert_test_data():conn = get_db()cursor = conn.cursor()# 准备测试数据test_articles = [{'title': '人工智能发展现状与未来趋势','content': '''人工智能技术正在快速发展,从机器学习到深度学习,从计算机视觉到自然语言处理,各个领域都取得了突破性进展。本文将详细介绍AI领域的最新发展动态和未来发展方向。近年来的主要突破:1. 大规模语言模型的突破2. 自动驾驶技术的进展3. AI在医疗领域的应用未来展望:- 更强大的多模态AI系统- 更高效的算法和架构- 更广泛的商业应用场景''','author': '张智能','likes': 42},{'title': '5G技术应用与产业变革','content': '''5G作为新一代移动通信技术,正在深刻改变着各个行业。本文将分析5G技术在工业互联网、智慧城市等领域的具体应用案例。主要应用领域:1. 工业自动化2. 远程医疗3. 车联网4. 智慧城市建设产业影响:- 制造业智能化转型- 服务业数字化升级- 新业态快速涌现''','author': '李网络','likes': 38},{'title': '区块链技术与金融创新','content': '''区块链技术正在重塑金融服务业,从支付结算到供应链金融,带来了全新的业务模式和机遇。本文深入分析区块链在金融领域的创新应用。技术优势:1. 去中心化2. 不可篡改3. 智能合约应用场景:- 跨境支付- 供应链金融- 数字货币- 资产数字化''','author': '王区块','likes': 25}]# 插入测试数据for article in test_articles:# 随机生成过去7天内的时间random_days = timedelta(days=random.randint(0, 7),hours=random.randint(0, 23),minutes=random.randint(0, 59))publish_time = datetime.now() - random_dayscursor.execute("INSERT INTO articles (title, content, author, publish_time, likes) ""VALUES (%s, %s, %s, %s, %s)",(article['title'], article['content'], article['author'],publish_time, article['likes']))conn.commit()cursor.close()conn.close()print("测试数据插入成功!")if __name__ == '__main__':import randominsert_test_data()

5.templates/index.html

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>博客点赞系统</title><link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"><style>.article-card {transition: transform 0.2s;cursor: pointer;}.article-card:hover {transform: translateY(-5px);box-shadow: 0 4px 15px rgba(0,0,0,0.1);}.like-btn {transition: all 0.2s;padding: 8px 12px;border-radius: 50%;width: 45px;height: 45px;display: flex;align-items: center;justify-content: center;}.like-btn:hover {transform: scale(1.1);}.like-btn .fa-heart {font-size: 1.2em;}.like-btn.liked {background-color: #ff4757;border-color: #ff4757;color: white;}.like-btn.liked:hover {background-color: #ff6b81;border-color: #ff6b81;}.like-count {font-size: 0.9em;color: #666;margin-top: 5px;}</style>
</head>
<body><div class="container py-5"><h1 class="text-center mb-5">博客文章</h1><div class="row">{% for article in articles %}<div class="col-md-6 mb-4"><div class="card article-card"><div class="card-body"><h5 class="card-title article-title" data-id="{{ article.id }}">{{ article.title }}</h5><div class="d-flex justify-content-between align-items-center"><div class="text-muted"><small>作者: {{ article.author }}</small><br><small>发布时间: {{ article.publish_time.strftime('%Y-%m-%d %H:%M') }}</small></div><div class="text-center"><button class="btn btn-outline-primary like-btn {% if article.user_liked %}liked{% endif %}"data-id="{{ article.id }}"><i class="{% if article.user_liked %}fas{% else %}far{% endif %} fa-heart"></i></button><div class="like-count mt-1" id="likes-{{ article.id }}">{{ article.likes }} 赞</div></div></div></div></div></div>{% endfor %}</div></div><!-- 文章内容模态框 --><div class="modal fade" id="articleModal" tabindex="-1"><div class="modal-dialog modal-lg"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">文章内容</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body"><div id="articleContent"></div></div></div></div></div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script><script>$(document).ready(function() {// 点赞功能$('.like-btn').click(function(e) {e.stopPropagation();const btn = $(this);const articleId = btn.data('id');const heartIcon = btn.find('i');$.post(`/like/${articleId}`, function(data) {$(`#likes-${articleId}`).text(data.likes + ' 赞');if (data.action === 'liked') {btn.addClass('liked');heartIcon.removeClass('far').addClass('fas');} else {btn.removeClass('liked');heartIcon.removeClass('fas').addClass('far');}});});// 查看文章内容$('.article-title').click(function() {const articleId = $(this).data('id');$.get(`/article/${articleId}`, function(data) {$('#articleContent').html(data.content);$('#articleModal').modal('show');});});});</script>
</body>
</html>

相关文章:

19.Python实战:实现对博客文章的点赞系统

Flask博客点赞系统 一个基于Flask的简单博客系统&#xff0c;具有文章展示和点赞功能。系统使用MySQL存储数据&#xff0c;支持文章展示、点赞/取消点赞等功能。 功能特点 文章列表展示文章详情查看&#xff08;模态框展示&#xff09;点赞/取消点赞功能&#xff08;每个IP只…...

【stm32】定时器输出PWM波形(hal库)

一. PWM基本原理 PWM是一种通过调节信号的占空比&#xff08;Duty Cycle&#xff09;来控制输出平均电压的技术。占空比是指高电平时间与整个周期时间的比值。例如&#xff1a; - 占空比为50%时&#xff0c;输出平均电压为电源电压的一半。 - 占空比为100%时&#xff0c;输出始…...

当Ollama遇上划词翻译:我的Windows本地AI服务搭建日记

&#x1f680; 实现Windows本地大模型翻译服务 - 基于OllamaFlask的划词翻译实践 &#x1f6e0;️ 步骤概要1️⃣ python 环境准备2️⃣ Ollama 安装3️⃣ 一个 Flask 服务4️⃣ Windows 服务化封装5️⃣ 测试本地接口6️⃣ 配置划词翻译自定义翻译源7️⃣ 效果展示8️⃣ debug…...

Linux上Elasticsearch 集群部署指南

Es 集群部署 Es 集群部署 Es 集群部署 准备好三台服务器。示例使用&#xff1a;110.0.5.141/142/143 1、es用户和用户组创建&#xff0c;使用root账号 groupadd esuseradd -g es es2、将es安装包和ik分词器上传到&#xff1a;/home/es/目录下&#xff08;任意目录都行&#…...

字节Trae使用感想(后端)

前言 昨天分享了字节哥的Trae从0到1创作模式构建一个vue前端项目&#xff0c;今天又来试试她的后端项目能力。不是我舔&#xff0c;不得不说确实不错。可惜现在曾经没有好好学习&#xff0c;进不了字节。既然进不了字节&#xff0c;那我就用字节哥的产品吧。 后面有惊喜…...

国产编辑器EverEdit - 二进制模式下观察Window/Linux/MacOs换行符差异

1 换行符格式 1.1 应用场景 稍微了解计算机历史的人都知道&#xff0c; 计算机3大操作系统&#xff1a; Windows、Linux/Unix、MacOS&#xff0c;这3大系统对文本换行的定义各不相同&#xff0c;且互不相让&#xff0c;导致在文件的兼容性方面存在一些问题&#xff0c;比如它们…...

文心一言4月起全面免费,6月底开源新模型:AI竞争进入新阶段?

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、文心一言免费化的背后&#xff1a;AI成本与应用的双重驱动1️⃣成本下降&#xff0c;推动文心一言普及2…...

解锁机器学习算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…...

如何使用Three.js制作3D月球与星空效果

目录 1. 基本设置2. 创建星空效果3. 创建月球模型4. 添加中文3D文字5. 光照与相机配置6. 动画与控制7. 响应式布局8. 结语 在本文中&#xff0c;我们将一起学习如何利用Three.js实现一个3D月球与星空的效果&#xff0c;并添加一些有趣的元素&#xff0c;比如中文3D文字和互动功…...

SQL语句语法

SQL数据库的结构为 库database 表table 段segment 行row 列column 或field SQL 语句主要分为以下几类&#xff1a; 数据定义语言&#xff08;DDL&#xff09;&#xff1a;用于定义数据库对象&#xff0c;如数据库、表、视图、索引等。数据操作语言&#xff08;DML&#xff09;&…...

github上文件过大无法推送问题

GitHub 对文件大小有限制&#xff0c;超过 100 MB 的文件无法直接推送到仓库中。 解决思路&#xff1a; 使用 Git Large File Storage (Git LFS) 来管理大文件不上传对应的大文件 使用Git LFS&#xff1a; 1. 安装 Git LFS 首先&#xff0c;你需要安装 Git LFS。可以按照以…...

微信小程序的请求函数封装(ts版本,uniapp开发)

主要封装函数代码&#xff1a; interface HttpOptions {url: string;method?: string;headers?: { [key: string]: string };data?: any; }class Http {private timeout: number;private baseUrl: string;public constructor() { this.timeout 60 * 1000;this.baseUrl ht…...

Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件

步骤1 开始通过 WSL 使用 VS Code | Microsoft Learn 点击远程开发扩展包。 步骤2 Remote Development - Visual Studio Marketplace 点击install&#xff0c; 允许打开Visual Studio Code。 步骤3 共有4项&#xff0c;一齐安装。 步骤4 在WSL Linux(Ubuntu)中&#xf…...

openAI最新o1模型 推理能力上表现出色 准确性方面提升 API如何接入?

OpenAI o1模型在回答问题前会进行深入思考&#xff0c;并生成一条内部推理链&#xff0c;使其在尝试解决问题时可以识别并纠正错误&#xff0c;将复杂的步骤分解为更简单的部分&#xff0c;并在当前方法无效时尝试不同的途径。据悉&#xff0c;o1不仅数学水平与美国奥林匹克竞赛…...

GC 基础入门

什么是GC&#xff08;Garbage Collection&#xff09;&#xff1f; 内存管理方式通常分为两种&#xff1a; 手动内存管理&#xff08;Manual Memory Management&#xff09;自动内存管理&#xff08;Garbage Collection, GC&#xff09; 手动内存管理 手动内存管理是指开发…...

Go语言协程Goroutine高级用法(一)

什么协程 在Go语言中&#xff0c;协程就是一种轻量的线程&#xff0c;是并发编程的单元&#xff0c;由Go来管理&#xff0c;所以在GO层面的协程会更加的轻量、高效、开销更小&#xff0c;并且更容易实现并发编程。 轻量级线程 Go语言中协程&#xff08;线程&#xff09;与传…...

DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件

1 DeepSeek处理自有业务的案例&#xff1a;让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强&#xff0c;如果不能在企业的自有业务上产生助益&#xff0c;那基本也是一无是处。将企业的自有业务上传到线上训练&#xff0c;那是脑子进水的做法&#xff…...

【鸿蒙HarmonyOS Next实战开发】lottie动画库

简介 lottie是一个适用于OpenHarmony和HarmonyOS的动画库&#xff0c;它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画&#xff0c;并在移动设备上进行本地渲染。 下载安裝 ohpm install ohos/lottieOpenHarmony ohpm 环境配置等更多内容&#xff0c…...

PAT乙级真题 — 1084 外观数列(java)

外观数列是指具有以下特点的整数序列&#xff1a; d, d1, d111, d113, d11231, d112213111, ...它从不等于 1 的数字 d 开始&#xff0c;序列的第 n1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d&#xff0c;所以就是 d1&#xff1b;第 2 项是 1 个 d&#xff08;对…...

从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地

导读&#xff1a;日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案&#xff0c;替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度&#xff0c;规模达到…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...