文章目录
代码实现篇
创建数据库
- 利用命令提示符登录数据库(方法在准备篇,这里不做阐述)
- 创建一个名为db_info的数据库(SQL语句)
create database db_info charset utf8;
代码框架
主程序(app.py)
-
from flask import Flask, render_template, request, make_response, send_file from models import Admin, Student, Project from exts import db import config, os from methods import get_Info, to_Data, to_List, to_Json, new_avatar_name, create_xlsx from flask_cors import * app = Flask(__name__) CORS(app, supports_credentials = True) # 解决跨域问题 app.config.from_object(config) db.init_app(app) url = "http://127.0.0.1:5000/" @app.route('/') def index(): #return render_template('index.html') return ("首页") @app.route('/login', methods=['POST']) # 登录 def login(): data = to_Data() account = data['account'] password = data['password'] if account and password: admin = Admin.query.filter(Admin.Adminaccount == account, Admin.Password == password).first() if admin: return ("1") return ("0") @app.route('/by_input', methods = ['POST']) # 按输入查询 def by_input(): data = to_Data() # 将json转为字典 input = data['input'] page = data['page'] if input and page: info = get_Info(input = input) #从数据库获取成员信息 list = to_List(info, page) #将数据转为列表 data = to_Json(list) #将列表数据转为json return data return ("0") @app.route('/by_name', methods = ['POST']) # 按姓名查询 def by_name(): data = to_Data() sname = data['name'] page = data['page'] if sname and page: info = get_Info(sname = sname) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_group', methods = ['POST']) # 按组别查询 def by_group(): data = to_Data() group = data['group'] page = data['page'] if group and page: info = get_Info(group = group) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_grade', methods = ['POST']) # 按年级查询 def by_grade(): data = to_Data() grade = data['grade'] page = data['page'] if grade and page: info = get_Info(grade = grade) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_name_group', methods=['POST']) # 按姓名、组别查询 def by_name_group(): data = to_Data() sname = data['name'] group = data['group'] page = data['page'] if sname and group and page: info = get_Info(sname = sname, group = group) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_name_grade', methods=['POST']) # 按姓名、年级 def by_name_grade(): data = to_Data() sname = data['name'] grade = data['grade'] page = data['page'] if sname and grade and page: info = get_Info(sname = sname, grade = grade) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_group_grade', methods=['POST']) # 按组别、年级 def by_group_grade(): data = to_Data() group = data['group'] grade = data['grade'] page = data['page'] if group and grade and page: info = get_Info(group = group, grade = grade) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/by_name_group_grade', methods=['POST']) # 按姓名、组别、年级查询 def by_name_group_grade(): data = to_Data() sname = data['name'] group = data['group'] grade = data['grade'] page = data['page'] if sname and group and grade and page: info = get_Info(sname = sname, group = group, grade = grade) list = to_List(info, page) data = to_Json(list) return data return ("0") @app.route('/up/image', methods=['POST']) # 上传头像 def up_image(): sno = request.form.get('sno') # sno = "20182109xxxx" avatar = request.files['image_data'] # 上传图片数据名 if sno and avatar: student = Student.query.filter(Student.SNo == sno).first() # 查找相应成员 if student: basedir = os.path.dirname(__file__) # 运行路径 avatar_path = os.path.join(basedir, 'static\image', new_avatar_name(avatar.filename)) # 重命名后合成文件在服务器的路径 avatar_path = avatar_path.replace('\\','/') # 若不换成/ Linux服务器会报错 位置:static/image/*.jpg avatar.save(avatar_path) # 保存文件 avatar_url = url + avatar_path # 合成头像访问路径 old_url = student.Avatar if old_url: # 判断是否存在,若存在删除存储的旧头像 old_url = old_url.replace(url,'') # 除去路径中的url os.remove(old_url) student.Avatar = avatar_url # 将链接存储在数据库 db.session.add(student) db.session.commit() return ("1") return ("0") @app.route('/add_change/info', methods=['POST']) # 添加或修改成员数据 def add_change_info(): data = to_Data() sno = data['sno'] avatar = url + "static/image/0.png" # 默认头像 sname = data['name'] grade = data['grade'] group = data['group'] ID = data['ID'] # 从前端获取得需要修改数据项目的ID列表 state = data['state'] # 添加或修改 data_pro = data['project_arr'] telephone = data['contact']['phone'] wechat = data['contact']['wx'] qq = data['contact']['qq'] mailbox = data['contact']['email'] other = data['contact']['other'] occupation = data['graduation']['job'] workaddress = data['graduation']['address'] direction = data['graduation']['study'] if sno and sname and grade and group: if state == 0: # 修改 student = Student.query.filter(Student.SNo == sno).first() # student.SNo = sno # 学号作为主键不可更改 student.SName = sname student.Group = group student.Grade = grade student.Telephone = telephone student.WeChat = wechat student.QQ = qq student.MailBox = mailbox student.Other = other student.Occupation = occupation student.WorkAddress = workaddress student.Direction = direction db.session.add(student) # 修改成员数据 db.session.commit() # 提交 for data in data_pro: if data['ID'] == 0: project = data['name'] award = data['prize'] code = data['code'] project = Project(SNo=sno, Project=project, Award=award, Code=code) db.session.add(project) # 添加项目数据 db.session.commit() if ID: for id in ID: project = Project.query.filter(Project.ID == id).first() if project: for data in data_pro: if data['ID'] == id: project.Project = data['name'] project.Award = data['prize'] project.Code = data['code'] db.session.add(project) # 修改项目数据 db.session.commit() return ("1") elif state == 1: # 增加 student = Student.query.filter(Student.SNo == sno).first() if not student: student = Student(SNo=sno, Avatar=avatar, SName=sname, Grade=grade, Group=group, Telephone=telephone, WeChat=wechat, QQ=qq, MailBox=mailbox, Other=other, Occupation=occupation, WorkAddress=workaddress, Direction=direction) db.session.add(student) # 添加成员数据 db.session.commit() # 提交 for data in data_pro: project = data['name'] award = data['prize'] code = data['code'] project = Project(SNo=sno, Project=project, Award=award, Code=code) db.session.add(project) # 添加项目数据 db.session.commit() return ("1") return ("0") # 成员已经存在 return ("-1") # 学号、姓名不能为空 @app.route('/delete/info', methods = ['POST']) # 删除成员 def delete_info(): data = to_Data() sno = data['sno'] if sno: student = Student.query.filter(Student.SNo == sno).first() if student: old_url = student.Avatar if old_url: # 删除存储在服务器的头像 old_url = old_url.replace(url, '') # 除去路径中的url os.remove(old_url) Student.query.filter(Student.SNo == sno).delete() # 删除 db.session.commit() return ("1") return ("0") @app.route('/delete/pro', methods=['POST']) # 删除项目 def delete_pro(): data = to_Data() ID = data['ID'] if ID: Project.query.filter(Project.ID == ID).delete() db.session.commit() return ("1") return ("0") @app.route('/excel') def excel(): info = Student.query.filter().all() excel_path = create_xlsx(info) if excel_path: response = make_response(send_file(excel_path)) response.headers["Content-Disposition"] = "attachment; filename = {}".format('新思路成员信息一览表.xls'.encode().decode('latin-1')) # 将文件名(中文)utf-8编码转成 latin-1 编码 return response return ("0") if __name__ == '__main__': # app.run(host = '0.0.0.0', port = 80) # 若要配置在服务器上 app.run()
扩展(exts.py)
-
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
主程序用到的方法(methods.py)
-
from flask import request import json, re, datetime, random, os from models import Student, Project from werkzeug.utils import secure_filename import xlwt # 向excel表格写数据的库 def get_Info(sname = None, group = None, grade = None, input = None): info = None if sname: sname = re.sub(' ', "", sname) # 除去空格 sname = re.sub('\d+', "", sname) # 提取姓名 if sname and group and grade: info = Student.query.filter(Student.SName == sname, Student.Group == group, Student.Grade == grade).all() if not info: # 模糊查询 sname = "%" + sname + "%" # 模糊条件 info = Student.query.filter(Student.SName.like(sname)).all() elif sname and group: info = Student.query.filter(Student.SName == sname, Student.Group == group).all() if not info: # 模糊查询 sname = "%" + sname + "%" # 模糊条件 info = Student.query.filter(Student.SName.like(sname)).all() elif sname and grade: info = Student.query.filter(Student.SName == sname, Student.Grade == grade).all() if not info: # 模糊查询 sname = "%" + sname + "%" # 模糊条件 info = Student.query.filter(Student.SName.like(sname)).all() elif group and grade: info = Student.query.filter(Student.Group == group, Student.Grade == grade).all() elif sname: info = Student.query.filter(Student.SName == sname).all() if not info: # 模糊查询 sname = "%" + sname + "%" # 模糊条件 info = Student.query.filter(Student.SName.like(sname)).all() elif group: info = Student.query.filter(Student.Group == group).all() elif grade: info = Student.query.filter(Student.Grade == grade).all() elif input: input = re.sub(' ', "", input) # 除去空格 # 输入条件为学号查询 input_sno = re.sub('\D', "", input) # 提取数字 if len(input_sno) > 6: info = Student.query.filter(Student.SNo == input_sno).all() if not info: input_sno = "%" + input_sno + "%" info = Student.query.filter(Student.SNo.like(input_sno)).all() if not info: # 为姓名查询 input_name = re.sub('\d+',"",input) # 提取姓名 if len(input_name) >= 1: # 存在 info = Student.query.filter(Student.SName == input_name).all() if not info: # 模糊查询 input_name = "%" + input_name + "%" info = Student.query.filter(Student.SName.like(input_name)).all() if not info: # 为组别 input_group = re.sub('\d+', "", input) # 提取组别 if len(input_group) >= 1: # 存在 info = Student.query.filter(Student.Group == input_group).all() if not info: # 模糊查询 input_group = "%" + input_group +"%" info = Student.query.filter(Student.Group.like(input_group)).all() if not info: # 为年级查询 input_grade = re.sub('\D',"",input) # 提取年级 if 4 >= len(input_grade) >= 2:# 存在 info = Student.query.filter(Student.Grade == input_grade).all() if not info: input_grade = "%" + input_grade + "%" info = Student.query.filter(Student.Grade.like(input_grade)).all() if not info: info = [] return info def to_Data(): # data = request.get_data() # 获取前端数据 # data = str(data, 'utf-8') # 转utf-8 # data = json.loads(data) # json转字典 data = json.loads(request.get_data().decode("utf-8")) if data: return data else: return {} def to_Json(list = None): if list: data = json.dumps(list, ensure_ascii = False) else: data = "0" return data def to_List(info, page): # page为页数 list = [] limit = 10 # 限制返回数据条数 index = len(info) # 行索引 for row in range(index): dic_stu = { 'sno': info[row].SNo, 'image_url':info[row].Avatar, 'name': info[row].SName, 'grade': info[row].Grade, 'group': info[row].Group, 'contact':{ 'phone': info[row].Telephone, 'wx': info[row].WeChat, 'qq': info[row].QQ, 'email': info[row].MailBox, 'other': info[row].Other }, 'graduation':{ 'job': info[row].Occupation, 'address': info[row].WorkAddress, 'study': info[row].Direction }, } list_pro = [] pro_info = Project.query.filter(Project.SNo == info[row].SNo).all() for row_ in range(len(pro_info)): dic_pro = { 'ID':pro_info[row_].ID, 'name': pro_info[row_].Project, 'prize': pro_info[row_].Award, 'code': pro_info[row_].Code } list_pro.append(dic_pro) dic_stu['project_arr'] = list_pro list.append(dic_stu) # 合并 total = limit * page list = list[total-limit:total] # 索引,位置 return list def new_avatar_name(avatar_name): now_time = datetime.datetime.now().strftime("%Y%m%d%H%M%S") rand_num = random.randint(10,99) # 随机10到99 name = secure_filename(avatar_name) ext = name.rsplit('.', 1)[1] # 扩展名 avatar_name = str(now_time) + str(rand_num) + '.' + ext # 合成 return avatar_name def create_xlsx(info): workbook = xlwt.Workbook(encoding = 'utf-8') worksheet = workbook.add_sheet('新思路成员信息一览表', cell_overwrite_ok = True) alignment = xlwt.Alignment() # 对齐格式 alignment.horz = xlwt.Alignment.HORZ_CENTER # 水平居中 alignment.vert = xlwt.Alignment.VERT_CENTER # font = xlwt.Font() # 字体 font.bold = True # 设置黑体 pattern = xlwt.Pattern() pattern.pattern = xlwt.Pattern.SOLID_PATTERN pattern.pattern_fore_colour = 27 # 浅色 borders = xlwt.Borders() borders.left = xlwt.Borders.THIN # THIN:实线 NO_LINE:无 DASHED:虚线 borders.right = xlwt.Borders.THIN borders.top = xlwt.Borders.THIN borders.bottom = xlwt.Borders.THIN borders_ = xlwt.Borders() borders_.bottom = xlwt.Borders.THIN tall = xlwt.easyxf('font:height 700;') worksheet.row(0).set_style(tall) tall = xlwt.easyxf('font:height 360;') worksheet.row(1).set_style(tall) tall = xlwt.easyxf('font:height 360;') worksheet.row(2).set_style(tall) worksheet.col(0).width = 256*13 # 学号 worksheet.col(4).width = 256*12 # 电话 worksheet.col(5).width = 256*12 # 微信 worksheet.col(6).width = 256*12 # QQ worksheet.col(7).width = 256*18 # 邮箱 worksheet.col(10).width = 256*15 # 地址 worksheet.col(11).width = 256*27 # 方向 worksheet.col(13).width = 256*25 worksheet.col(14).width = 256*25 worksheet.col(15).width = 256*25 worksheet.col(16).width = 256*25 worksheet.col(17).width = 256*25 style0 = xlwt.XFStyle() style0.alignment = alignment style0.font = font style0.pattern = pattern style0.borders = borders worksheet.write_merge(0, 0, 0, 17, 'New-Thread成员信息一览表', style0) style1 = xlwt.XFStyle() style1.alignment = alignment style1.font = font style1.borders = borders worksheet.write_merge(1, 1, 0, 3, '个人信息', style1) worksheet.write_merge(1, 1, 4, 8, '联系方式', style1) worksheet.write_merge(1, 1, 9, 11, '毕业去向(工作/研究生/留学生)', style1) worksheet.write_merge(1, 1, 12, 17, '参与项目', style1) style2 = xlwt.XFStyle() style2.alignment = alignment style2.borders = borders a = ['学号','姓名','年级','组别','电话','微信','QQ','邮箱','其它','职业','地址(工作单位)','研究方向(岗位/研究生技术方向)','-','项目1','项目2','项目3','项目4','项目5'] for i in range(18): worksheet.write(2, i, a[i], style2) style3 = xlwt.XFStyle() style3.alignment = alignment style3.borders = borders if info: i = 3 # 控制行 pi = 3 for row in range(len(info)): stu_info = [info[row].SNo, info[row].SName, info[row].Grade, info[row].Group, info[row].Telephone, info[row].WeChat, info[row].QQ, info[row].MailBox, info[row].Other, info[row].Occupation, info[row].WorkAddress, info[row].Direction] j = 0 # 控制信息列 pj = 13 # 工程列 for content in stu_info: worksheet.write_merge(i, i+2, j, j, content, style3) # 合并单元格参数(从0开始): 1-3行,0-0列,内容,格式 j = j+1 if j == 12: break style4 = xlwt.XFStyle() style4.borders = borders_ worksheet.write(i, 12, '项目名称') worksheet.write(i+1, 12, '获奖情况') worksheet.write(i+2, 12, '源码', style4) project = Project.query.filter(Project.SNo == info[row].SNo).all() for row in range(len(project)): pro_info = [project[row].Project, project[row].Award, project[row].Code] for content in pro_info: worksheet.write(pi, pj, content, style3) pi = pi+1 # 加行 pj = pj + 1 # 加列 pi = pi - 3 # 还是一个学生,所以回到这一次的初始行 i = i + 3 # 隔行输出 pi = pi + 3 # 下一初始行 basedir = os.path.dirname(__file__) # 运行路径 excel_path = os.path.join(basedir, 'static', '新思路成员信息一览表.xls') # 重命名后合成文件在服务器的路径 excel_path = excel_path.replace('\\', '/') # 若不换成/ Linux服务器会报错 位置:static/*.xls workbook.save(excel_path) # 写入 return excel_path return ("0")
数据库配置信息(config.py)
- config.py
DIALECT ='mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'password' # 此处填写你的数据库密码 HOST = 'localhost' # 部署到服务器不能用127.0.0.1 得用localhost PORT = '3306' DATABSE = 'db_info' # 此处为你建的数据库的名称 SQLALCHEMY_DATABASE_URI ="{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABSE) SQLALCHEMY_TRACK_MODIFICATIONS = False
创建相应数据库模型(models.py)
- models.py
from exts import db class Admin(db.Model): __tablename__ = 'admin' Adminaccount = db.Column(db.String(255, 'utf8_general_ci'), primary_key=True) Password = db.Column(db.String(255, 'utf8_general_ci'), nullable=False) class Project(db.Model): __tablename__ = 'project' ID = db.Column(db.Integer, primary_key=True) SNo = db.Column(db.ForeignKey('student.SNo', ondelete='CASCADE', onupdate='CASCADE'), nullable=False, index=True) Project = db.Column(db.String(255)) Award = db.Column(db.String(255)) Code = db.Column(db.String(255)) student = db.relationship('Student', primaryjoin='Project.SNo == Student.SNo', backref='projects') class Student(db.Model): __tablename__ = 'student' SNo = db.Column(db.String(255, 'utf8_general_ci'), primary_key=True, index=True) Avatar = db.Column(db.String(255, 'utf8_general_ci'), index=True) SName = db.Column(db.String(255, 'utf8_general_ci'), nullable=False) Grade = db.Column(db.String(255, 'utf8_general_ci'), nullable=False) Group = db.Column(db.String(255, 'utf8_general_ci'), nullable=False) Telephone = db.Column(db.String(255, 'utf8_general_ci')) WeChat = db.Column(db.String(255, 'utf8_general_ci')) QQ = db.Column(db.String(255, 'utf8_general_ci')) MailBox = db.Column(db.String(255, 'utf8_general_ci')) Other = db.Column(db.String(255, 'utf8_general_ci')) Occupation = db.Column(db.String(255, 'utf8_general_ci')) WorkAddress = db.Column(db.String(255, 'utf8_general_ci')) Direction = db.Column(db.String(255, 'utf8_general_ci'))
将models中所写模型映射到数据库中(manager.py)
-
from flask_script import Manager from flask_migrate import Migrate, MigrateCommand from app import app from exts import db manager = Manager(app) migrate = Migrate(app,db) # 使用Migrate绑定app和db manager.add_command('db',MigrateCommand) #添加迁移脚本的命令到manager中 if __name__ == '__main__': manager.run()
-
映射
打开命令提示符,切换到项目文件目录cd /d D:\Flask\成员信息管理系统
执行以下命令
python manager.py db init
python manager.py db migrate
python manager.py db upgrade
上一篇(准备篇):https://blog.csdn.net/qq_42766994/article/details/89401754
下一篇(测试篇):https://blog.csdn.net/qq_42766994/article/details/89436536