L1.2.4 flask_todo

开发流程

  1. 立项。我们打算做一个TODO应用
  2. 大致规划,竞品分析,交互图(产品)。
  3. 技术选型。flask mongo数据库 bookstrap。
  4. 开始编码。先搭个架子。根据业务结构确定方法、类名、引用资源。
  5. 完成一个基础流程(展示列表)或先给假数据搭建静态页面或完成一个基础流程(get展示列表)
  6. 完成add, update,delete功能
  7. bookstrap美化
    未完成的todo排到已完成的前面,未完成的里面创建时间早的排前面.
    增加显示一列 todo列表的创建时间。
    查询时格式化时间,不要毫秒。
from flask import Flask,url_for, redirect, render_template, request
import pymongo
from  bson.objectid import ObjectId
from datetime import datetime

app = Flask(__name__)
# 数据库实例
content = pymongo.MongoClient('127.0.0.1', 27017)
db = content.todo
# mongo TODO文档结构
class Todo(object):
    '''
    一行待办事项数据结构。添加。
    字段:事项内容,添加创建时间,状态(未完成、已完成),完成时间
    '''
    @staticmethod
    def create_doc(self, content):
        return {
            'content': content,
            'create_time': datetime.now(),
            'status': 0,   # 0未完成  1已完成
            'finish_time': None
        }


@app.route('/')
def index():
    return redirect(url_for('get'))

@app.route('/get')
def get():
    '''展示todo列表'''
    # todo_list = db.todo.find({}).sort([('status',1), ('create_time',1)])
    # print(todo_list)
    todos = db.todo.find({}).sort([('status',1), ('create_time',1)])    # 返回迭代器,只能遍历一次,时间格式化最好在数据库查询语句中处理
    todo_list2 = []
    for todo in todos:
        todo_list = {}
        todo_list['_id'] = todo['_id']
        todo_list['status'] = todo['status']
        todo_list['content'] = todo['content']
        todo_list['create_time'] = todo['create_time'].strftime('%Y-%m-%d %H:%M:%S')
        todo_list2.append(todo_list)
    return render_template('index.html', todo_list=todo_list2)

@app.route('/add', methods=['POST'])
def add():
    '''添加一条todo'''
    form = request.form
    content = form['content']
    print(content)
    affected_id = db.todo.insert({
            "content": content,
            "create_time": datetime.now(),
            "status": 0,
            "finish_time": None
        })
    print(affected_id)
    if affected_id:
        return redirect(url_for('index'))

@app.route('/finish')
def finish():
    '''更新状态已完成'''
    args = request.args
    _id = args['_id']
    affect_id = db.todo.update(
        {"_id": ObjectId(_id)},
        {
            "$set":{
                "status": 1,
                "finish_time": datetime.now()
            }
         }
    )
    print(affect_id)
    return redirect(url_for('index'))

@app.route('/delete')
def delete():
    '''删除无用的todo'''
    args = request.args
    _id = args['_id']
    print(_id)
    affected_id = db.todo.remove({
        "_id": ObjectId(_id)
    })
    print(affected_id)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run()
  • base.html ↓
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <!-- bookstrap css js, jquery-->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
  <script src="https://cdn.bootcss.com/twitter-bookstrap/4.1.3/js/bookstrap.js"></script>

</head>
<body>
{% block content %}
{% endblock %}

</body>
</html>
  • index.html ↓
{% extends 'base.html' %}
{% block title %}待办事项程序{% endblock %}

{% block content %}
 <!-- 导航 -->
<div id="navigation" class="container">
 <nav class="navbar navbar-default navbar-inverse">
   <div class="navbar-header">
     <a class="navbar-brand" href="#" ><span class="glyphicon glyphicon-th-list"></span>TODO</a>
   </div>
 </nav>
</div>

  <!-- 添加todo表单 -->
<div id="todo-add " class="container">
 <form action="{{ url_for('add') }}" method="post" class="form-inline" >
   <textarea rows=5 cols=50 placeholder="请输入待办事项" name="content"></textarea>
   <button type="submit" class="btn btn-success btn-lg" style="height: 50px;">添加</button>
 </form>
</div>

<div class="divider"></div>

<!-- todo列表 -->
<div id="todo-list" class="container">
 <table class="table table-striped">
   <th>
     <td>状态</td>
     <td>创建时间</td>
     <td>内容</td>
     <td>删除</td>
     <td>完成</td>
   </th>
   {% for todo in todo_list %}
     <tr>
     <td>{{ loop.index0 }}</td>
     {% if todo.status == 0 %}
       <td><span class="glyphicon glyphicon-asterisk btn-warning"></span></td>
     {% elif todo.status == 1 %}
       <td><span class="glyphicon glyphicon-asterisk btn-success"></span></td>
     {% endif %}
     <td>{{ todo.create_time }}</td>
     <td>{{ todo.content }}</td>
     <td><a href="{{ url_for('delete', _id=todo._id) }}"><span class="glyphicon glyphicon-remove"></span></a></td>
     <td><a href="{{ url_for('finish', _id=todo._id) }}"><span class="glyphicon glyphicon-ok"></span></a></td>
    {# {{ todo._id }} #}
     </tr>
   {% endfor %}
 </table>
</div>
{% endblock %}

效果如图:
在这里插入图片描述

遇到的问题

  1. 有关flask框架的报错。浏览器开发者工具中观察请求的url,观察后台日志url,print看有没有视图方法。看报错信息,看报错栈中自己的代码出错的那一行
  2. mongo根据objectId删除有问题,排查中。
  3. cdn,bootcss.com 提供的cdn有问题导致样式无法出来。解决 使用官方下载中提供的cdn
  4. push项目到码云时失败。一是要先关联远程和本地仓库。二是要输出正确码云密码,如果输入错误要先删除windows凭据。
  5. 关于时间的最佳设计,数据库冗杂,查询语言中格式化时间。
  6. 游标取值为迭代器,只能循环一遍。可以复制一份到普通变量中或再次查询(建议)。
    7.content键报错没有键错误,经捡代码正确,原因数据库插入时某一行错误缺少content字段,导致查询时报错。 可以看出nosql数据库数据一致性不如关系型数据库。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值