当前位置: 首页 > 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>
http://www.lryc.cn/news/537397.html

相关文章:

  • 【stm32】定时器输出PWM波形(hal库)
  • 当Ollama遇上划词翻译:我的Windows本地AI服务搭建日记
  • Linux上Elasticsearch 集群部署指南
  • 字节Trae使用感想(后端)
  • 国产编辑器EverEdit - 二进制模式下观察Window/Linux/MacOs换行符差异
  • 文心一言4月起全面免费,6月底开源新模型:AI竞争进入新阶段?
  • 解锁机器学习算法 | 线性回归:机器学习的基石
  • 如何使用Three.js制作3D月球与星空效果
  • SQL语句语法
  • github上文件过大无法推送问题
  • 微信小程序的请求函数封装(ts版本,uniapp开发)
  • Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件
  • openAI最新o1模型 推理能力上表现出色 准确性方面提升 API如何接入?
  • GC 基础入门
  • Go语言协程Goroutine高级用法(一)
  • DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
  • 【鸿蒙HarmonyOS Next实战开发】lottie动画库
  • PAT乙级真题 — 1084 外观数列(java)
  • 从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地
  • STM32——HAL库开发笔记19(串口中断接收实验)(参考来源:b站铁头山羊)
  • 清影2.0(AI视频生成)技术浅析(二):自然语言处理
  • Unity序列化多态数组
  • Spring Framework 中文官方文档
  • 力扣-二叉树-257 二叉树的所有路径
  • 如何调整 Nginx工作进程数以提升性能
  • FreeRTOS-rust食用指南
  • 如何使用智能化RFID管控系统,对涉密物品进行安全有效的管理?
  • 0基础学LabVIEW
  • Go语言精进之路读书笔记(第二部分-项目结构、代码风格与标识符命名)
  • Windows server 2016 无法部署docker问题