利用flask从0开发一个TODOlist

利用 flask 从 0 开发一个 TODOlist

0x00、环境准备

Python 环境的安装

直接去百度搜 Python 进官网找到自己适合的版本进行安装

编辑器的准备

  • VSCODE 下新建一个工作文件夹 flask

  • 控制台下pip install virtualenv

  • 进入 flask 文件夹下,virtualenv venv创建虚拟环境,避免外界影响

    image-20210628095018555

  • cd venv后再执行Scripts\activate可激活虚拟环境,deactivate即可退出虚拟环境。

image-20210628095256688

  • 进入虚拟环境后再进行 flask 报的安装pip install flask flasksqlalchemy,即可~

0x02、写一个 falsk 的 helloworld

  • 在 flask 目录新建一个 app.py 的文件

    输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from flask import Flask

    app = Flask(__name__)

    @app.route('/')

    def index():
    return 'hello world!'

    if __name__ == "__main__":
    app.run(debug=True)
  • 在控制台输入python app.py即可启动服务[当前目录哦~]

  • 在浏览器输入 localhost5000 即可看到显示的 helloworld!

0x03、模板引擎 Jinja2 语法介绍

Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全。 ###什么是模板引擎?
就是在一个静态 HTML 加入一些类似变量的标签,然后引擎在渲染这个 HTML 时候会动态的把变量填入内容,生成一个最终的 HTML。
Jinja2 是一个模版语言,只是类似 Python,比较符合 Python 语法,但不完全相同!
###Jinja2 语法 ####常见标记

1
2
3
4
5
6
7
8
9
10
11
注释:`{# 这是注释 #}`
变量:`{{ post.title }}`,或字典元素 `{{your_dict['key']}}`,或列表 `{{your_list[0]}}`
多行代码块:`{% 开始 %} HTML 标签 {% 结束 %}`

{% if user %}
{{ user }}
{% else %}
hello!
{% for index in indexs %}
{{ index }}
{% endfor %}

####分隔符

1
2
3
4
{% ... %} 语句
{{ ... }}打印出模板输出的表达式
{# ... #}注释
#... ## 行语句

####变量
除了普通的字符串变量,Jinja2 还支持列表、字典和对象,你可以这样获取变量值:

1
2
3
4
{{ mydict['key'] }}
{{ mylist[3] }}
{{ mylist[myintvar] }}
{{ myobj.somemethod() }}

0x04、扩展

flask 文件夹下新建 static 和 templates 两个文件夹,分别用来存放 html 文件和 css 文件

image-20210628210025489

app.py 中 import render_template,在 temlates 文件夹下新建 index.html,再把return 'hello world!'改为return index.html,就可以以另一种形式显示你的hello world

在 base.html 文件加入 jinja2 语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <link rel="stylesheet" href="static/css/main.css"> -->
<link rel="stylesheet" href="{{url_for('static',filename='css/main.css')}}" />
{% block head %} {% endblock %}
</head>
<body>
{% block body %} {% endblock %}
</body>
</html>

在 index.html 文件中写整体框架:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{% extends 'base.html' %} {% block head %}
<title>Task Master</title>
{% endblock %} {% block body %}
<div class="content">
<h1 style="text-align: center">Task Master</h1>
{% if tasks|length < 1 %}
<h4 style="text-align: center">There are no tasks. Create one below!</h4>
{% else %}
<table>
<tr>
<th>Task</th>
<th>Added</th>
<th>Actions</th>
</tr>
{% for task in tasks %}
<tr>
<td>{{ task.content }}</td>
<td>{{ task.date_created.date() }}</td>
<td>
<a href="/delete/{{task.id}}">Delete</a>
<br />
<a href="/update/{{task.id}}">Update</a>
</td>
</tr>
{% endfor %}
</table>
{% endif %}

<div class="form">
<form action="/" method="POST">
<input type="text" name="content" id="content" />
<input type="submit" value="Add Task" />
</form>
</div>
</div>
{% endblock %}

app.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from flask import Flask, render_template, url_for,request,redirect
from flask_sqlalchemy import SQLAlchemy#引入数据库
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)

class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)


def __repr__(self):
return '<Task %r>' % self.id

@app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'POST':
# pass
# return 'hello'
task_content = request.form['content']
new_task = Todo(content=task_content)

try:
db.session.add(new_task)
db.session.commit()
return redirect('/')
except:

return 'There was an issue adding your task'
else:
tasks = Todo.query.order_by(Todo.date_created).all()
return render_template('index.html',tasks=tasks)
# return render_template('index.html')


@app.route('/delete/<int:id>')
def delete(id):
task_to_delete = Todo.query.get_or_404(id)

try:
db.session.delete(task_to_delete)
db.session.commit()
return redirect('/')
except:
return 'There was a problem deleting that task'


@app.route('/update/<int:id>', methods=['GET', 'POST'])
def update(id):
task = Todo.query.get_or_404(id)

if request.method == 'POST':
task.content = request.form['content']

try:
db.session.commit()
return redirect('/')
except:
return 'There was an issue updating your task'

else:
return render_template('update.html', task=task)


if __name__ == "__main__":
app.run(debug=True)

为了使网页美观再加点 css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
body,
html {
margin: 0;
font-family: sans-serif;
background-color: lightgreen;
}

.content {
margin: 0 auto;
width: 400px;
}

table,
td,
th {
border: 1px solid #aaa;
}

table {
border-collapse: collapse;
width: 100%;
}

th {
height: 30px;
}

td {
text-align: center;
padding: 5px;
}

.form {
margin-top: 20px;
}

#content {
width: 70%;
}

还有一个 update.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{% extends 'base.html' %} {% block head %}
<title>Task Master</title>
{% endblock %} {% block body %}
<div class="content">
<h1 style="text-align: center">Update Task</h1>

<div class="form">
<form action="/update/{{task.id}}" method="POST">
<input type="text" name="content" id="content" value="{{task.content}}" />
<input type="submit" value="Update" />
</form>
</div>
</div>
{% endblock %}

控制台运行python app.py

image-20210628212136496

image-20210628212413428

大功告成啦!


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!