我的博客小项目
又花了一阵时间重新组织了一下我的博客这个小项目,将原来的单文件编程扩展到了多文件编程,将逻辑层、显示层、数据层、进行了分离,同时加入了日志功能,数据写入文件。待完善(文章写入文件,后续会改造项目使用面对对象封装数据,将用户和文章分别封装,然后使用网络构造服务器,数据存入mysql数据库)。
本系统主要包括了用户模块和文章模块,用户模块包含了用户注册、用户登陆、维护个人信息、修改密码等几个小模块,文章模块包含了两个小模块,查看所有用户的文章,维护自己的文章。
系统涉及知识点:字典、元组、列表、字符串的使用,用字典封装跳转菜单,数据、视图与逻辑的分离,面向过程编程。
部分调试截图
用户登陆选择界面
博客主页
我的文章管理
维护个人资料
查看个人信息
修改个人信息
系统源码:
blog模块
"""我的博客 author: version:v1.0.0 """ import menu import service def engin(): """程序引擎""" # 展示登陆界面 menu.show_login() # 处理流程 def main(): """程序入口""" service.record("程序启动\n") engin() # 主程序入口 if __name__ == "__main__": main()
data模块
"""数据存储""" import os import json # 获取用户列表 def get_users(): """连接数据库,获取用户列表""" # 若文件存在打开文件 if os.path.isfile("files/users.json"): with open("files/users.json", "r", encoding="utf-8") as f: users = json.loads(f.read()) return users else: return False # 更新用户列表 def update_users(): # 将用户列表写入文件 if os.path.isfile("files/users.json"): with open("files/users.json", "w", encoding="utf-8") as f: f.write(json.dumps(users, ensure_ascii=False)) return True else: return False # 更新在线用户列表 def update_online_users(): # 将用户列表写入文件 if os.path.isfile("files/online_users.json"): with open("files/online_users.json", "w", encoding="utf-8") as f: f.write(json.dumps(online_users, ensure_ascii=False)) return True else: return False # 所有用户字典 users = get_users() # 所有在线用户字典 online_users = get_users() # 所有的文章字典 all_articles = dict() def main(): """程序入口""" users = get_users() # 测试将用户账号为1的密码改为"2" # users.get("1")["password"] = "2" update_users(users) if __name__ == '__main__': main()
menu模块
""" 菜单界面跳转 author: version:v1.0.0 """ import os import sys import time import service # 用户登陆选择界面 def show_login(): """用户登陆选择界面""" os.system("cls") print("","*"*45, "\n\t\t我的博客登陆界面\n", "*"*45) print("\t\t1. 用户登陆\n\t\t2. 用户注册\n\t\t3. 退出系统\n", "*"*45) # 程序进入用户登陆界面 service.record("用户进入登陆选择界面") # 用户选择跳转 choice = input("请输入您的选择:") service.record("用户输入选择%s" % choice) return login_menu_dict.get(choice)() if choice in login_menu_dict else show_login() # 用户登陆界面 def login(): """用户登陆界面""" os.system("cls") print("","\n\t\t欢迎您的登陆\n", "*"*45) service.record("用户进入用户登陆界面") # 验证成功,展示主页 if service.login(): service.record("验证成功进入主页") show_index() # 验证失败,返回登陆界面 else: service.record("验证失败") show_login() # 用户注册界面 def register(): """用户注册界面""" os.system("cls") print("","\n\t\t欢迎您前来注册\n", "*"*45) service.record("用户进入注册界面") # 调用注册 service.register() # 展示登陆界面 show_login() # 我的博客主页 def show_index(): """我的博客主页""" os.system("cls") print("","*"*45, "\n\t\t我的博客主页\n","*"*45) print("\t\t1. 查看所有文章\n\t\t2. 我的文章管理\n\t\t3. 维护个人资料") print("\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45) service.record("用户进入我的主页界面") # 用户选择跳转 choice = input("请输入您的选择:") service.record("用户输入%s" % choice) # 执行跳转菜单 return index_menu_dict.get(choice)() if choice in index_menu_dict else show_index() # 查看所有文章 def look_all_articles(): """查看所有文章""" service.record("用户进入查看所有文章界面") os.system("cls") print("", "\n\t\t查看所有文章\n", "*" * 45) # 显示所有未删除的文章 print("编号\t标题\t\t作者\t浏览次数\t\t发布时间") for article in service.my_articles: # 若文章为删除 if not article.get("is_del"): # 构建显示文章 show_article = (article.get("no"), article.get("title"), article.get("author").get("username"), article.get("read_count"), article.get("time")) print("%s\t%s\t\t%s\t%s\t\t%s" % show_article) # 用户输入选择 print("\n1.查看文章 2.返回上一级 3.退出系统") choice = input("请输入您的选择:") service.record("用户输入选择%s" % choice) # 跳转菜单 return look_all_articles_menu_dict.get(choice)() if choice in look_all_articles_menu_dict else look_all_articles() # 我的文章管理 def show_manager_my_articles(): """我的文章管理""" os.system("cls") print("", "*"*45, "\n\t\t管理我的文章\n", "*"*45) print("\t\t1. 查看我的所有文章\n\t\t2. 发表文章\n\t\t3. 回收站\n\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45) service.record("用户进入我的文章管理界面") # 用户选择跳转 choice = input("请输入您的选择:") service.record("用户输入选择%s" % choice) # 跳转菜单 return manager_my_articles_menu_dict.get(choice)() if choice in manager_my_articles_menu_dict else show_manager_my_articles() # 查看我的所有文章 def look_my_articles(): """查看我的所有文章""" service.record("用户进入查看我的所有文章界面") os.system("cls") print("", "\n\t\t查看我的所有文章\n", "*" * 45) # 显示我的文章 print("编号\t标题\t\t作者\t浏览次数\t\t发布时间") for article in service.my_articles: # 若为自己的文章 if article.get("author") == service.user and not article.get("is_del"): # 构建显示文章 show_article = (article.get("no"), article.get("title"), article.get("author").get("username"), article.get("read_count"), article.get("time")) print("%s\t%s\t\t%s\t%s\t\t%s" % show_article) # 用户输入选择 print("\n1.查看文章 2.删除文章 3.返回上一级 4.退出系统") choice = input("请输入您的选择:") service.record("用户输入%s" % choice) # 跳转菜单 return look_my_articles_menu_dict.get(choice)() if choice in look_my_articles_menu_dict else look_my_articles() # 发表文章 def publish_article(): """发表文章""" service.record("用户进入发表文章界面") os.system("cls") print("", "\n\t\t发表文章\n", "*" * 45) service.publish_article() # 查看我的一篇文章 def look_article(): """查看我的一篇文章""" service.record("用户查看我的文章界面") os.system("cls") print("", "*"*40,"\n文章内容\n","*"*40) service.look_article() # 删除文章 def del_article(): """删除我的文章""" service.record("用户删除文章界面") os.system("cls") print("", "\n\t\t删除我的文章\n", "*" * 45) service.del_article() # 回收站 def recycle(): """回收站""" service.record("用户进入回收站界面") os.system("cls") print("", "\n\t\t回收站\n", "*" * 45) # 显示我的文章 print("编号\t标题\t\t作者\t\t浏览次数\t发布时间") for article in service.my_articles: # 若为自己的文章 if article.get("is_del"): # 构建显示文章 show_article = (article.get("no"), article.get("title"), article.get("content"), article.get("read_count"), article.get("time")) print("%s\t%s\t\t%s\t%s\t%s" % show_article) choice = input("\n输入文章编号恢复文章,其他任意键返回") service.record("用户输入恢复文章的编号%s" % choice) for article in service.my_articles: if choice == str(article.get("no")) and article.get("is_del"): article["is_del"] = False service.record("恢复文章%s成功"% choice) input("恢复成功,按任意键继续!") return recycle() else: service.record("返回") input("文章不存在,按任意键继续!") return show_manager_my_articles() # 维护个人信息 def show_manager_my_info(): """维护个人信息""" service.record("用户进入维护个人信息界面") os.system("cls") print("","*"*45, "\n\t\t维护个人信息\n", "*"*45) print("\t\t1. 查看个人信息\n\t\t2. 修改个人信息\n\t\t3. 修改密码") print("\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45) # 用户选择跳转 choice = input("请输入您的选择:") service.record("用户输入选择%s菜单跳转" % choice) # 跳转菜单 return manager_my_info_menu_dict.get(choice)() if choice in manager_my_info_menu_dict else show_manager_my_info() # 查看个人信息 def look_my_info(): """查看个人信息""" service.record("用户进入查看个人信息界面") os.system("cls") print("", "\n\t\t查看我的信息界面\n", "*" * 45) show_info = (service.user.get("account"),service.user.get("username"), service.user.get("email"), service.user.get("sex"), service.user.get("age"), service.user.get("phone"), service.user.get("address")) print("\t\t账号:%s\n\t\t昵称:%s\n\t\t邮箱:%s\n\t\t性别:%s\n\t\t年龄:%s\n\t\t手机号码:%s\n\t\t地址:%s" % show_info) choice = input("\n按R键返回,其他任意键修改个人信息") service.record("用户输入%s" % choice) if choice.upper() =='R': service.record("返回上一级") return show_manager_my_info() else: service.record("修改个人信息") return update_my_info() # 修改个人信息 def update_my_info(): """修改个人信息""" service.record("用户进入修改个人信息界面") os.system("cls") print("", "\n\t\t修改个人信息界面\n", "*" * 45) print("\t1.修改昵称\n\t2.修改性别\n\t3.修改年龄\n\t4.修改手机号码\n\t5.修改地址\n\t6.返回上一级\n\t7.退出系统") choice = input("\n请输入您的选择:") service.record("用户输入%s跳转菜单" % choice) if choice in ["1", "2", "3", "4", "5"]: return service.update_my_info(choice) else: return update_my_info_menu_dict.get(choice)() if choice in update_my_info_menu_dict else update_my_info() # 修改密码 def update_password(): """修改密码""" service.record("用户进入修改密码界面") os.system("cls") print("", "\n\t\t修改密码界面\n", "*" * 45) return service.update_password() def exit_system(): """退出系统""" service.record("用户正常退出系统") for i in range(0,3): print("系统将在{}秒后退出".format(3-i)) time.sleep(1) sys.exit(1) # 用户登陆界面菜单,1登陆博客2.注册账号3.退出系统 login_menu_dict = {"1": login, "2": register, "3": exit_system} # 主页菜单,1查看所有文章2.管理我的文章3.维护个人信息4.返回上一级5退出系统 index_menu_dict = {"1": look_all_articles, "2": show_manager_my_articles, "3": show_manager_my_info, "4": show_login, "5": exit_system} # 查看所有文章菜单,1.查看文章 2.返回上一级 3.退出系统 look_all_articles_menu_dict = {"1": look_article, "2": show_index, "3": exit_system} # 管理我的文章菜单,1.查看我的所有文章,2.发表文章3.删除文章4。回收站5.返回上一级6.退出系统 manager_my_articles_menu_dict = {"1": look_my_articles, "2": publish_article, "3": recycle, "4": show_index, "5": exit_system} # 维护个人信息菜单,1查看个人信息2.修改个人信息3.修改密码4.返回上一级5.退出系统 manager_my_info_menu_dict = {"1": look_my_info, "2": update_my_info, "3": update_password, "4": show_index, "5": exit_system} # 查看我的所有文章菜单,1查看文章 2.删除文章 3.返回上一级 4.退出系统 look_my_articles_menu_dict = {"1": look_article, "2": del_article, "3": show_manager_my_articles, "4": exit_system} # 修改个人信息菜单 update_my_info_menu_dict = {"6": show_manager_my_info, "7": exit_system} # 处理流程 def main(): """程序入口""" show_login() # look_my_articles() # 主程序入口 if __name__ == "__main__": main()
service模块
"""业务逻辑的处理""" import data import random import menu import datetime # 用户登陆 def login(): """用户登陆验证""" # 连接数据库获取用户列表 users = data.get_users() in_account = input("请输入您的账号或邮箱:") record("用户输入账号或邮箱%s" % in_account) in_password = input("请输入您的密码:") record("用户输入密码%s" % in_password) # 遍历用户列表,获取用户字典 for sql_user in users.values(): # 用户输入的账号或email正在且密码正在,验证成功 if (in_account == sql_user.get("account") or in_account == sql_user.get("email")) \ and (in_password == sql_user.get("password")): # 如果在线用户不为空,将当前用户加入字典中 if data.online_users: data.online_users[in_account] = data.users.get(in_account) # 在线用户为空,将在线用户指向当前用户(因为在线用户为空则不是字典,为布尔值) else: data.online_users = data.users.get(in_account) record("用户登陆成功") # 添加当前在线用户,将当前在线用户添加到在线用户列表 global user user = data.users.get(in_account) data.update_online_users() return True else: record("用户登陆失败,账号或密码错误") return False # 用户注册 def register(): """用户注册函数""" # 获取数据库用户字典 record("用户注册账号") users = data.users # 用户输入昵称密码 username = input("请输入您的昵称(按R返回上一级):") record("用户输入用户昵称%s(R放弃注册)" % username) # 用户放弃注册,返回上一级 if username.upper() == "R": record("用户放弃注册") return menu.show_login() # 用户输入密码 in_password = input("请输入您的密码:") record("用户输入密码%s" % in_password) in_confirm = input("请确认您的密码:") record("用户输入确认密码%s" % in_confirm) # 判断用户密码是否包含特殊字符 if not in_password.isalnum(): input("密码只能是字母和数字,按任意键继续!") return register() # 用户密码长度只能是6~20位 if not (6 <= len(in_password) <= 20): input("密码长度必须为6~20位,按任意键继续!") return register() # 前后密码一致 if in_password == in_confirm: # 随机生成9位数账号 account = "" count = 9 while True: while count: account += str(random.randint(0,9)) count -= 1 # 若账号存在重新生成,不存在退出循环 if account in users: continue else: break # 将用户添加到数据库 user = {"account": account, "password": in_password, "username": username, "email": account+"@bk.com"} data.users[account] = user data.update_users() record("注册成功,获得账号:%s邮箱:%s" % (account,account+"@bk.com")) print("恭喜您注册成功,您的账号为:%s邮箱为:%s\n请牢记您的账号!" % (account, account+"@bk.com")) input("按任意键继续") # 前后密码不一致 else: record("注册失败" ) input("前后密码输入不一致,按任意键继续!") return register() # 发表文章 def publish_article(): """发表文章""" record("用户发表文章") title = input("请输入文章的标题:") record("用户输入标题%s" % title) content = input("请输入文章的内容:") record("用户输入文章内容%s" % content) article = {"no": len(my_articles) + 1, "title": title, "content": content, "author": user, "time": get_current_time(), "read_count": 0, "is_del": False} # 将当前文章添加到我的所有文章列表中 my_articles.append(article) data.all_articles[user.get("account")] = my_articles input("发布成功,按任意键继续!") return menu.show_manager_my_articles() # 查看一篇文章 def look_article(): """查看我的一篇文章""" no = input("请输入要查看的文章编号:") record("用户输入文章编号%s" % no) for article in my_articles: if no == str(article.get("no")) and not article.get("is_del"): print(article.get("content")) article["read_count"] += 1 break else: record("文章不存在") input("文章不存在,按任意键返回!") return menu.show_index() record("查看成功") # 查看成功 input("按任意键返回") return menu.show_index() # 删除文章 def del_article(): """删除文章""" no = input("输入要删除文章的编号(按R返回):") record("用户输入要删除的文章编号%s或返回上一级" % no) # 按R返回 if no.upper() == "R": record("返回上一级") return menu.look_my_articles() for article in my_articles: if no == str(article.get("no")) and not article.get("is_del"): article["is_del"] = True break else: record("文章不存在,删除失败") input("文章不存在,按任意键返回!") return menu.look_my_articles() record("成功删除文章编号为%s" % no) # 成功删除 input("文章以删除,按任意键返回") return menu.look_my_articles() # 完善个人信息 def update_my_info(choice): """完善个人信息""" # 用户输入修改的信息为 new_info = input("\n请输入您的新信息:") record("用户输入新信息%s" % new_info) info_list = ["username", "sex", "age", "phone", "address"] user[info_list[int(choice)-1]] = new_info data.users[user.get("account")] = user data.update_users() record("修改信息成功") input("修改成功,按任意键继续!") return menu.look_my_info() # 修改密码 def update_password(): """修改密码""" old_password = input("请输入您的原密码(按R放弃修改):") record("用户输入原密码%s(R返回上一级)" % old_password) if old_password.upper() == "R": record("返回上一级") return menu.show_manager_my_info() # 密码验证成功 if old_password == user.get("password"): new_password = input("请输入您的新密码:") record("原密码正确,用户输入新密码%s" % new_password) confirm_password = input("请确认您的新密码:") record("用户输入确认新密码为%s" % confirm_password) # 新密码与原密码相同 if old_password == new_password: record("前后密码不一致") input("新密码不能与原密码相同,按任意键继续!") return menu.update_password() # 判断用户密码是否包含特殊字符 if not new_password.isalnum(): record("密码中包含特殊字符") input("密码只能是字母和数字,按任意键继续!") return menu.update_password() # 用户密码长度只能是6~20位 if not (6 <= len(new_password) <= 20): record("密码长度不在6~20位之间") input("密码长度必须为6~20位,按任意键继续!") return menu.update_password() # 前后密码不一致 if not new_password == confirm_password: record("前后密码不一致") input("前后密码不一致,按任意键继续!") return menu.update_password() # 修改成功 else: record("修改成功,新密码为%s" % new_password) user["password"] = new_password # 更新用户字典,并将其写入数据库 data.users[user.get("account")] = user data.update_users() input("修改密码成功,请牢记您的密码!按任意键返回") return menu.show_manager_my_info() # 验证失败 else: record("修改失败") input("密码不正确,按任意键继续") return menu.update_password() # 日志函数 def record(msg): """记录日志函数""" with open("files/blog.log", "a", encoding="utf-8") as f: f.write(get_current_time()+":"+msg+"\n") # 定义当前时间函数 def get_current_time(): """获取当前时间""" t = datetime.datetime.now() return "%s年%s月%s日 %s:%s:%s" % (t.year, t.month, t.day, t.hour, t.minute, t.second) # 当前在线的用户 user = dict() # 当前用户文章列表 my_articles = list() # 主程序入口 def main(): """程序入口""" login() # publish_article() if __name__ == '__main__': main()
数据文件(文件在files目录下)
有序不知道怎么导入文件,用文字说明数据存储,文件的目录结构为: ----blog---项目目录 ----------blog.py---- ----------data.py---- ----------menu.py---- ----------service.py---- ----------__init__.py--- ----------files-----数据文件夹 ---------------------online_user.json----在线用户json数据 ---------------------users.json----所有用户json数据 ---------------------blog.log-----系统日志文件 用户数据结构如下{"1": {"account": "1", "password": "1", "username": "lisa", "email": "1@bk.com"}}
结语:由于初学python,本项目为练习项目有很多待完善的地方,在后续的学习中会继续完善本项目。