利用 flask 从 0 开发一个 TODOlist
0x00、环境准备
Python 环境的安装
直接去百度搜 Python 进官网找到自己适合的版本进行安装
编辑器的准备
VSCODE 下新建一个工作文件夹 flask
控制台下pip install virtualenv
进入 flask 文件夹下,virtualenv venv
创建虚拟环境,避免外界影响
cd venv
后再执行Scripts\activate
可激活虚拟环境,deactivate
即可退出虚拟环境。
- 进入虚拟环境后再进行 flask 报的安装
pip install flask flasksqlalchemy
,即可~
0x02、写一个 falsk 的 helloworld
在 flask 目录新建一个 app.py 的文件
输入
| 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 语法 ####常见标记
| 注释:`{# 这是注释 #}` 变量:`{{ post.title }}`,或字典元素 `{{your_dict['key']}}`,或列表 `{{your_list[0]}}` 多行代码块:`{% 开始 %} HTML 标签 {% 结束 %}`
{% if user %} {{ user }} {% else %} hello! {% for index in indexs %} {{ index }} {% endfor %}
|
####分隔符
| {% ... %} 语句 {{ ... }}打印出模板输出的表达式 {# ... #}注释 #... ## 行语句
|
####变量
除了普通的字符串变量,Jinja2 还支持列表、字典和对象,你可以这样获取变量值:
| {{ mydict['key'] }} {{ mylist[3] }} {{ mylist[myintvar] }} {{ myobj.somemethod() }}
|
0x04、扩展
flask 文件夹下新建 static 和 templates 两个文件夹,分别用来存放 html 文件和 css 文件
app.py 中 import render_template
,在 temlates 文件夹下新建 index.html,再把return 'hello world!'
改为return index.html
,就可以以另一种形式显示你的hello world
!
在 base.html 文件加入 jinja2 语法:
| <!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="{{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': 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)
@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
| {% 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
大功告成啦!