流程一览

  • 前言
  • 1.实现效果
    • 1. 首页
    • 2. 登录
    • 3. 注册
    • 4. 用户界面
    • 5. 代码详情
    • 6. 上传页面
  • 2.一些讲解
  • 3.遇见的问题和解决(要点)
    • 1. echarts的使用和下载 码云
    • 2. 文件解压问题 byteio
    • 3. wtforms自定义validate
    • 4. html的table的滑动条
    • 5. flask的handler的错误处理
    • 6. pipreqs好用
    • 7. mysql的连表子查询
    • 8. 闪现的使用或者g,jinjia模板不能在{{}}里调用字符串的[0]
    • 9. html的textarea的运用
    • 10. Flask的自定义扩展 (2020-02-17更新)

前言

  最近在看flask的课程,根据视频的要求做了一个flask的小项目:代码统计系统。简单的完善了一下。
  不得不说虽然只是一个小项目,但是也是有完整的目录结构的,所以就不讲解代码了。
  编译环境及工具,库:

  • pycharm,anaconda,mysql,redis
  • sqlalchemy,wtforms,redis,redis-py,flask,pipreqs,flask-migrate,flask-script,flask-sqlalchemy,flask-session

  mysql驱动的话用这个mysql-connector-python,不用pymysql

# 先 pip install mysql-connector-python
class BaseConfig(object):# ###flask-sqlalchemy的配置###SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://root:password@127.0.0.1:3306/你的数据库名?charset=utf8"

1.实现效果

  先上目录结构:

1. 首页

2. 登录

3. 注册

4. 用户界面

柱状图有序显示用户的总代码提交量

5. 代码详情

折线图根据日期有序显示代码提交趋势

6. 上传页面

上传代码压缩包给服务器,得到里面的代码写的总行数

2.一些讲解

  用的mysql做数据保存,用sqlalchemy库来做orm,不用原生sql,并且使用flask-sqlalchemy库更贴合flask来进行开发。使用wtfoems库来做登陆和注册表单,更简洁高效。使用pipreqs库来合成项目的requirements,方便的显示所使用的第三方库。使用flask-script和flask-migrate,因flask-migrate依赖于flask-script,其参数migrate生成数据库更改命令,upgrate进行数据库更改,能更简洁高效的对数据库进行更改。
  flask因其特性,不可避免的会使用大量的第三方库,合理的使用资源才可提高效率。
  以下是项目的打包,echarts的js包。(免费)

  1. 代码提交系统
  2. echarts的js包

3.遇见的问题和解决(要点)

1. echarts的使用和下载 码云

  因为echarts的js包是在github上的,下载很慢还会中断,所以我帮你们下载下来了。我用的是码云的办法,在网上可以搜到。使用的话有说明文档,解决基本功能还是可以的。

2. 文件解压问题 byteio

   这是一个很重要的问题,因为之前的方法没用了。

# 保存解压后的文件(原压缩文件不保存)
# obj.stream是flask上传后取到的文件流,有open()功能
target_path = "保存路径"
shutil._unpack_zipfile(obj.stream, target_path)

     如果你直接把stream放进去的话,会报错:

AttributeError: 'SpooledTemporaryFile' object has no attribute 'seekable'

     可能flask返回的并非真正的文件对象,所以没有’seekable’参数,改为如下就可以了:

from io import BytesIO
temp = BytesIO(obj.stream.read())
target_path = "保存路径"
shutil._unpack_zipfile(temp, target_path)
3. wtforms自定义validate

  为了检查用户名是否别人已经注册过了,而且wtforms没有对比的方法,就自己自定义,如下:

class RegisterForm(Form):name = simple.StringField(label='用户名:',validators=[validators.DataRequired(message='用户名不可为空!'),validators.Length(min=2, max=12, message='用户名长度必须大于%(min)d且小于%(max)d'),],render_kw={'placeholder': '请输入用户名:', 'id': 'name'})@staticmethoddef validate_name(self, filed):  # validate是必须的前缀,后面的name是上面对应组件的对象名name = db.session.query(models.Users.name).filter(models.Users.name == filed.data).first()db.session.remove()if name:raise ValidationError("用户名:%s 已存在!" % name)
4. html的table的滑动条

  html的table很难看,而且如果限制显示区域就有上下和左右的滑动条,添加如下属性则隐藏:

table{width: 60%;margin: 10px auto;border-collapse: collapse;/*border-collapse:collapse合并内外边距(去除表格单元格默认的2个像素内外边距*/background-color: rgba(0,0,0,0);table-layout: fixed;
}
/*table可滚动start*/
tbody{display: block;height: 250px;overflow-y: auto;overflow-x: hidden !important;-webkit-overflow-scrolling: touch; /*为了滚动顺畅*/
}
table tbody::-webkit-scrollbar {display: none; /*隐藏滚动条*/
}
thead, tbody tr{display: table;width: 100%;table-layout: fixed;
}
table thead{width: 100%;
}
/*table可滚动end*/

     虽然是隐藏了,但是当数据多的时候也没有下拉滚动条,只能滚动鼠标轮,所以最好的是当数据多的超出了table范围的时候自动显示下拉滚动,未超出时就隐藏。

5. flask的handler的错误处理

  flak处理错误的时候不能在蓝图里面,必须在全局app上,如下:

def create_app():app = Flask(__name__)app.config.from_object('settings.ProConfig')app.debug = True@app.errorhandler(404)def page_not_found(error):return render_template("ac_404.html", error=error), 404app.register_blueprint(account)app.register_blueprint(administration)# Session(app)db.init_app(app)return app

     还有就是处理 413错误(上传文件过大) 的时候,没有返回,上传文件过大,无法处理,只能提醒,且会断开链接。

6. pipreqs好用

  python的pipreqs库挺好用的,会自动生成所引用的第三方库,不过我觉得还是有一些缺陷所在,但是基本问题不大!

7. mysql的连表子查询

  比如查询一个人在另一张表里的所有代码总数和。

subqry = db.session.query(db.func.sum(models.CodeMes.code_line)).filter(models.Users.id == models.CodeMes.user_id).correlate(models.Users).as_scalar()  # 生成mysql语句不查询
index_result = db.session.query(models.Users, subqry).order_by(subqry.desc()).all()
db.session.remove()
8. 闪现的使用或者g,jinjia模板不能在{{}}里调用字符串的[0]

   原本我以为flask的闪现很鸡肋,后来用到了发现还是有一点用的,场景:比如我注册成功了,跳转到登陆界面,那么界面下应该“显示注册成功,请登录”吧,但是flask的跳转函数

return redirect("login")

是没有可以传参的。但是从注册成功到跳转登陆界面只是一次请求,所以flask的g对象可以完成这个,因为g就是只存在一次请求中就消失的。不过用闪现可能简单点,就先用它了。

flash("注册成功,请登录!", 'success')success = ''
if get_flashed_messages(category_filter=['success']):success = get_flashed_messages(category_filter=['success'])[0]
# 因为jinjia模板不能在html的{{}}里调用字符串的[0],而get_flashed_messages()函数返回的是列表,所以就在后端的处理里直接取[0]了。
9. html的textarea的运用

  因为在注册或登陆时如果你的信息不符合要求,应该要有返回错误的,那么如何接受以及放在合适的位置就很重要了。而textarea就勉强符合要求:

<textarea id="error1" cols="30" rows="3" readonly disabled>{% for field in form %}{{field.errors[0]}}{% endfor %}{{user_pwd_error}}
</textarea>
#error1{position: absolute;top: 230px;right: 30px;resize: none;color: red;background-color: rgba(0,0,0,0);border: none;
}


     设为只读,控制长宽和位置

10. Flask的自定义扩展 (2020-02-17更新)

  很多时候我们会遇见如下情况:Flask的全局处理路由放到创建app的函数里,这样既不美观,也不方便,有其他办法吗?放到函数外面然后在内部调用?

from flask import Flask
# from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()  # 必须在蓝图之前,不然蓝图不能调用from exts.auth import Auth
from .views.account import account
from .views.administration import administration
from .models import *def create_app():app = Flask(__name__)app.config.from_object('settings.ProConfig')app.debug = TrueAuth(app, [administration])  # 因为对于蓝图的处理,所以这个地方必须放到蓝图注册之前。因为蓝图在注册的时候会对所有的蓝图函数进行添加处理。app.register_blueprint(account)app.register_blueprint(administration)@app.errorhandler(404)def xxx():print('xxx')return 'xxx'# Session(app)db.init_app(app)return app

    这时就要涉及一个知识点了,就是python的装饰器是如何实现的!

# 方法一
@app.errorhandler(404)
def xxx():print('xxx')return 'xxx'
# 方法二
def page_not_found(self, error):return render_template("ac_404.html", error=error), 404
app.errorhandler(404)(self.page_not_found)

    基于如此我们就可以再开一个目录exts来存放全局处理的路由和函数了。

from flask import render_template, session, redirectclass Auth(object):def __init__(self, app=None, bluep_list=None):self.app = appif bluep_list is None:bluep_list = []self.bluep_list = bluep_listif app is not None:self.init_app(app)def init_app(self, app):app.auth_manager = selffor bluep in self.bluep_list:bluep.before_request(self.check_login)app.errorhandler(404)(self.page_not_found)# 这个函数可以处理一些值在全部的视图里直接使用,而不需要render_template()来导入值。app.context_processor(self.context_processor)def check_login(self):if not session.get('user_info'):return redirect("/login")def context_processor(self):user = session.get('user_info')  # 返回的变量可视图中全局使用return dict(current_user=user)def page_not_found(self, error):return render_template("ac_404.html", error=error), 404def login_session(self, login_result):session['user_info'] = {'id': login_result[0], 'nikename': login_result[1]}def logout_session(self):if 'user_info' in session:session.pop('user_info')

    如上的做法还处理了一个问题,当你的蓝图很多的时候,你还需要在很多的蓝图里使用before_request装饰器来验证用户是否登录,这是否也不符合程序的简洁性。所以我们使用外部扩展来处理,在Auth类里传入蓝图对象列表,然后for循环来添加before_request函数。

    这里还有一个小细节:因为对于蓝图的处理,所以外部的扩展处理 Auth(app, [administration]) 必须放到蓝图注册之前。因为蓝图在注册的时候会对所有的蓝图函数进行添加处理。

    为什么又要把登录,注销的处理也放到这里面嘞,因为可以对session里的值进行统一处理,不会分散多处。


  最后因能力有限,暂时就先这样,后面如果js和mysql学的好的话,还可以更丰富,特别时js感觉在前端里是真的强大!

后期可优化:

  • 限制每日提交一次
  • 使用正则来约束用户名和密码的格式
  • ajax传数据


感谢大家支持!人生苦短,我用python!

简约的Flask代码统计系统相关推荐

  1. 农村人口统计系统代码

    很抱歉,作为一个预训练的语言模型,我不能提供完整的代码.但是,我可以给您一些指导,帮助您编写农村人口统计系统的代码. 首先,您需要确定您要使用的编程语言,例如 Python.Java.C++等.然后, ...

  2. Python代码统计工具

    目录 Python代码统计工具 声明 一. 问题提出 二. 代码实现 三. 效果验证 Python代码统计工具 标签: Python 代码统计 声明 本文将对<Python实现C代码统计工具(一 ...

  3. ansible代码发布系统

    ansible - 代码发布系统 ssh 秘钥登录 ssh-keygen # 用来生成ssh的密钥对 ssh-copy-id 192.168.107.131 # 复制秘钥到远程主机 ansible 命 ...

  4. Flask框架-蓝图系统

    Flask之蓝图系统 一.创建蓝图 (1)在主项目下创建目录 (2)在目录下创建蓝图模块文件 (3)在文件中导入蓝图模块,创建实例对象,如何创建视图,创建路由 (4)在主项目文件,通过falsk实例对 ...

  5. 开源 php 报表,php网站流量统计系统-开源系统 | 学步园

    phpMyVisites phpMyVisites是一个网站流量统计系统,它能够提供非常详细的统计报告和高级图形报表.phpMyVisites不是一个Apache log分析工具,它建有自己的log. ...

  6. NBA球员生涯数据统计系统(中南大学C语言课设)

    自动化与电气类专业大一第一学期C语言的课程设计,留给后来的新生参考. 前排提醒:由于链表和文件不属于课程学习内容,且本人自学能力菜得真实,因此本人写的课设没有使用到链表(在学了在学了).但据本人同学所 ...

  7. 数据结构课设----运动会分数统计系统

    1.运动会分数统计 [问题描述] 参加运动会的n个学校编号为1 ~ n.比赛分成m个男子项目和w个女子项 目,项目编号分别为1~ m和m+1~ m+w.由于各项目参加人数差别较大,有 些项目取前五名, ...

  8. 运动会分数统计系统(数据结构)C++

    运动会分数统计系统(数据结构)C++ 参加运动会有n个学校,学校编号为1--n.比赛分成m个男子项目,和w个女子项目.项目编号为男子1--m,女子m+1--m+w.不同的项目取前五名或前三名积分:取前 ...

  9. 公交门户分析与统计系统

    摘  要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准 ...

最新文章

  1. CSS常用样式及示例
  2. SourceTree 基本介绍
  3. python中的序列类型和序列号_python~序列类型及操作
  4. hdu1428(spfa与记忆化搜索)
  5. [react] create-react-app创建新运用怎么解决卡的问题?
  6. 1 计算机网络体系结构与OSI参考模型
  7. 13亿美元的思想实验
  8. 菜鸟进阶Linux高手之路——第三天
  9. 漫步数学分析二十九——幂级数
  10. Ubuntu下如何修改文件或者文件夹的权限
  11. STM32WB55开发板(一)单板设计-硬件介绍
  12. 弹性系数和线径的计算公式_压缩弹簧的弹性系数计算
  13. ceph集群安装报错解决方法
  14. ftps软件android,透视相机软件ftp
  15. linux终端如何分栏,动态分栏布局实现
  16. 剪映+json解析将视频中的声音转换成文本
  17. 数字经济时代,达尔文平台助力广告投放走向数智化
  18. Hololens开发学习笔记——TrackedHandJoint关节点详解
  19. m2e-wtp的作用
  20. 软件开发项目规划时,SA、SD与SE的区别与重要性

热门文章

  1. w10计算机配置在哪,Win10怎么看电脑配置?Win10系统电脑配置查看方法图解
  2. CAJ文献转PDF文件
  3. 用Python做兼职接单,简直是爽到离普
  4. Python:赋值,copy和deepcopy区别
  5. Nokia E52的Runtime java.lang.Runtime Exception Toolkit Closed问题解决
  6. 微信小程序应用开发赛全国三等奖总结,以及关键点汇总,开发基本功系列(含云开发笔记、wxcharts数据可视化)
  7. 基于cw32f030c8t6的多功能语音播报提醒装置装置
  8. 发布v1.0.0.0 酷袋
  9. Vue2组件封装 Vue组件封装
  10. python爬虫项目——豆瓣Top250