• Flask任务列表项目


    需求分析

    开发一个任务列表项目,该项目实现的功能主要为任务列表的维护,包括任务的新建、修改、删除、查询等功能。

    本项目中一个任务可以代表一个事项,即描述一个准备完成的事情。任务可以是需求评审、用例开发、测试执行、项目上线等。

    每一个任务都有待执行、进行中、已完成、已废弃4种状态。

    当用户首次新建任务时,其状态默认为待执行,此阶段用户可以修改任务状态为进行中、已废弃;

    当任务状态为进行中时,用户可以修改任务状态为已完成、已废弃;任务为已完成、已废弃状态时,表示当前任务已结束,不再支持任务状态的修改。

    用户新建任务时,需要填写任务名称、执行时间、任务描述、执行人等信息。任务新建完成后,只有状态为待执行、进行中时,才可以修改任务的具体内容,当任务状态为已完成、已废弃时,不再支持对任务内容进行修改。

    创建的任务默认以列表的形式展示,列表的标题字段包括任务ID、任务名称、执行时间、执行人、创建时间、操作。其中操作字段包括查看、编辑、修改状态3个操作。任务列表默认以创建时间倒序排列,且默认只展示10条任务记录。

    模块及设计

    本项目为前后端分离开发模式,前端主要模块为任务列表页面、任务新建/修改页面、任务详情页面;后端主要模块为任务查询接口、任务新建/修改接口、任务详情接口、任务状态修改接口

    数据库设计

    本项目主要围绕任务的信息进行增、删、改、查等操作,因此只需要维护一张任务表即可。表中的字段需要包括需求分析中提到的所有字段。这里以MySQL数据库作为数据存储库,任务表的名称为task。

    1. CREATE TABLE `task` (
    2. `id` int(11) NOT NULL AUTO_INCREMENT,
    3. `name` varchar(100) NOT NULL COMMENT '任务名称',
    4. `desc` varchar(255) DEFAULT NULL COMMENT '任务描述',
    5. `start_time` timestamp NULL DEFAULT NULL COMMENT '执行开始时间',
    6. `end_time` timestamp NULL DEFAULT NULL COMMENT '执行结束时间',
    7. `assign` varchar(50) NOT NULL COMMENT '执行人',
    8. `status` enum('DISCARD','FINISHED','INPROCESS','INIT') NOT NULL DEFAULT 'INIT' COMMENT '状态',
    9. `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    10. `is_del` tinyint(1) DEFAULT '0' COMMENT ' 逻辑删除标识。0:未删除,1:已删除',
    11. PRIMARY KEY (`id`)
    12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    前端

    Vue开源框架-vue-element-admin-任务列表项目-CSDN博客

    后端

    在app.py中添加路由

    1. app.route('/api/todo', methods=['POST'])(todo)
    2. app.route('/api/todo/list')(get_todo_list)

    保存任务接口的功能是接收前端发送的POST请求,然后根据请求数据的情况来确定是新增还是更新任务。具体而言,如果用户请求中带有任务ID,说明该任务之前已经保存过,则会更新该任务;而如果用户请求中没有带任务ID,说明之前没有保存过该任务,则会新增一条任务数据。

    1. from flask import jsonify, request
    2. from model.todo import update_todo, create_todo
    3. def todo():
    4. data = request.json
    5. if data.get('id'): # 更新任务
    6. ret = update_todo(data)
    7. else: # 新增任务
    8. ret = create_todo(data)
    9. code = 0 if ret else -1
    10. return jsonify({
    11. "code": code,
    12. "msg": '',
    13. "data": ret
    14. })

    在model目录中新建一个名为todo.py的文件,并在文件中实现update_todo、create_todo函数。

    1. import logging
    2. from . import get_db
    3. def update_todo(data):
    4. sql = '''update todo set name=:name, 'desc'=:desc, start_time=:start_time,
    5. end_time=:end_time, assign=:assign, status=:status where id=:id'''
    6. try:
    7. get_db().query(sql, **data)
    8. return True
    9. except Exception as e:
    10. logging.exception(e)
    11. return False
    12. def create_todo(data):
    13. sql = '''insert into todo (name, 'desc', start_time, end_time, assign, status) values
    14. (:name, :desc, :start_time, :end_time, :assign, :status)'''
    15. try:
    16. get_db().query(sql, **data)
    17. return True
    18. except Exception as e:
    19. logging.exception(e)
    20. return False

    通过get_db函数获取DB的操作对象,之后执行组装好的SQL语句完成数据的更新和插入操作。get_db函数在model/__init__.py文件中实现,其具体代码如下:

    1. import records
    2. def get_db():
    3. conn = 'mysql+pymysql://{user}:{passwd}@{ip}:3306/${dbname}'
    4. return records.Database()

    任务列表接口的功能为获取符合当前查询要求的全部任务列表。目前任务的查询条件主要分为3类:当前任务、未完成任务、已完成任务。其中当前任务为待执行、进行中且当天有效的任务;未完成任务为所有待执行、进行中的任务;已完成任务为所有已完成、已废弃的任务。

    1. def get_todo_list():
    2. tab = request.args.get('tab')
    3. if tab == 'current':
    4. ret = get_current_todo()
    5. elif tab == 'unfinish':
    6. ret = get_unfinish_todo()
    7. elif tab == 'finished':
    8. ret = get_finished_todo()
    9. else:
    10. ret = []
    11. return jsonify({
    12. "code": 0,
    13. "msg": '',
    14. "data": ret
    15. })
    1. def get_current_todo():
    2. sql = '''select * from todo where status in ('INIT', 'INPROCESS') and start_time < :today and :today < end_time'''
    3. today = time.strftime("%Y-%m-%d", time.localtime())
    4. try:
    5. rows = get_db().query(sql, today=today).all(as_dict=True)
    6. return rows
    7. except Exception as e:
    8. logging.exception(e)
    9. return []
    10. def get_unfinish_todo():
    11. sql = '''select * from todo where status in ('INIT', 'INPROCESS')'''
    12. try:
    13. rows = get_db().query(sql).all(as_dict=True)
    14. return rows
    15. except Exception as e:
    16. logging.exception(e)
    17. return []
    18. def get_finished_todo():
    19. sql = '''select * from todo where status in ('FINISHED', 'DISCARD')'''
    20. try:
    21. rows = get_db().query(sql).all(as_dict=True)
    22. return rows
    23. except Exception as e:
    24. logging.exception(e)
    25. return []

    备注知识


    1、app.route('/api/todo', methods=['POST'])(todo)后面的todo为这个路径绑定的函数。

    2、data=request.json 为获取前端发送请求时带的请求参数,这里实际用到的是from flask import request这个库,而不是requests库。 
       request.json 只能够接受方法为POST、Body为raw,内容为 application/json类型的数据
       json.loads(request.dada) 能够同时接受方法为POST、Body为 raw类型的 Text或者 application/json类型的值
       request.args获取请求方法为get时的请求参数
       即params = request.json if request.method == "POST" else request.args
    另外:
        print('request.method', request.method)  # 获取请求方法
        print('request.url', request.url)  # 获取完整的URL
        # 请求头
        # print('request.headers', request.headers)  # 获取所有请求头里面的字段
        # print('request.cookies', request.cookies)

         print('request.json', request.json)

    3、获取任务数据时,根据任务状态做了区分,请求参数带了tab?
       因为 getTaskList(tab), pullData({ tab: tab })传入了tab
    后端处理时通过 tab = request.args.get('tab')取到tab的值

    4、前端vue文件中,获取列表的内容写在 mounted() {
        this.getTaskList(this.activeTab)
      },函数下,意思为加载时调用。

    5、@/utils/request.js 是基于 axios 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等
    export function submit(data) {
      return request({
        url: '/api/todo',
        method: 'post',
        headers: {
          'Content-Type': 'application/json'
        },
        data
      })
    }

    6、编辑任务接口时,请求参数带了created_time,为什么?

    编辑任务请求todo接口,打印出request.json,发现有created_time这个字段,但是页面的form没有,这个字段哪里来的?
    这个字段是表结构有的字段,创建数据时,mysql使用CURRENT_TIMESTAMP生成的 表示当插入数据的时候,该字段默认值为当前时间
    生成的时间,比如id,VUE文件里也没有,但是request.json也有。

    创建任务时,提交给后端的是抽屉页面form有的数据,是没有id和create_time的,编辑任务请求字段中才有这两个。
    所以这两个字段是什么时候在编辑时,跑到请求字段里的?

    其实在获取列表时,返回了一条数据的所有字段,
    rows = get_db().query(sql, today=today).all(as_dict=True)
            return rows

    前端的getTaskList调用pulldata时,把response.data赋值给了tableData,而页面显示的字段,都是从这个tableData获取的,
    为name,实际为tableData.name
    所以只要在页面上加入prop为id或者创建时间,既可以显示对应数据。

    另外注意编辑按钮的事件
     
      editTask(row) {
          this.title = '编辑任务'
          this.drawer = true
          this.form = row
        },
    编辑函数,把一行数据,都给了form,如果去掉scope.row这句话,点击编辑按钮,显示的页面数据为空。
    这也是为什么,请求数据的时候,会带上所有数据库有的字段,而不是form页面显示的字段。

    app.py中添加路由,controller下添加访问路径对应函数,model下实现调用用到的函数。

    总结:本文分享了一个flask的任务列表项目,并对后端实现内容做了详细的讲解。

  • 相关阅读:
    【C++】红黑树的模拟实现
    说一下 TCP/IP 协议?以及每层的作用?
    nginx--正向代理、反向代理及负载均衡(图解+配置)
    Windows11 环境安装Gradle
    Wordpress plugin removes ‘/category‘
    (二十)ATP应用测试平台——websocket实现微服务版在线客服聊天室实战案例
    【Qt】QPalette
    openGauss内核分析-统计信息与行数估计
    Kotlin内置函数let、run、apply的区别
    STARK中的FRI代码解析
  • 原文地址:https://blog.csdn.net/seanyang_/article/details/127679039