在开始之前,让我们先来聊聊 Django 与 Flask 。用装修风格来类比:一个是轻奢风格(下图左),一个是叙利亚风格(下图右):
Django 的使用更加惬意,大概就是租客口中的 ‘拎包入住’ 的模式,工具齐全,只需要考虑吃 肉夹馍(CBV)还是 4菜1汤(FBV),偶尔要换个冰箱(数据库)还得考虑合不合适。
而使用 Flask 就如同找了一个叙利亚风格的出租房,看上去很简陋,欸,实际上又什么都有(指 地板、天花板 ),不过想要别有一番风味,还得自己的喜好来布置。
#Ps:文章最后附上了项目全部的代码
编码工具各凭喜好,我这里使用的 Visio Studio Code ,由于要使用到 vue框架 ,我们要在一开始就把 Flask 跟 vue 区分开来,给他们安排上单人包间。也就是说新建两个文件夹,前后 端代码分开存放。
在后端文件夹中新建一个 app.py 来作为我们后端的主程序,在里面写入:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello, World!
"
大概就是这样子:
接着我们打开控制台,进入到 flask 文件夹中,在里面输入以下代码:
set FLASK_APP=app.py
# 设置 FLASK 环境变量,如果名称是 app.py 或者 wsgi.py 可以忽略这一句代码
flask run
# 启动
可以看到控制台输出了一个IP,在浏览器中打开:
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
这里我选用的是 Flask + SQLAlchemy + SQLite 作为我们的数据存储体系,在 app 中导入 SQLAlchemy:
from flask_sqlalchemy import SQLAlchemy
根据我们需要的字段,创建表:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.sqlite'
# 指定数据库文件
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 允许修改跟踪数据库
db = SQLAlchemy(app)
class Books(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), nullable=False)
author = db.Column(db.String(120), nullable=False)
read= db.Column(db.Boolean)
db.create_all()
# 创建表
重新运行 app.py 文件,可以看到数据库文件已经生成成,接下来我们定义几个函数便于我们对数据库的增删改查:
# 增
def insertData(title,author,read):
book=Books(title=title,author=author,read=read)
db.session.add_all([book])
db.session.commit()
# 查
def selectDataAll():
book_list=[]
books = Books.query.all()
# 类似于 select * from Books
for s in books:
dic = {}
dic['id'] = s.id
dic['title'] = s.title
dic['author'] = s.author
dic['read'] = s.read
print(f'Id: {s.id} | Title: {s.title} | Author: {s.author} | Read: {s.read}')
print('----')
book_list.append(dic)
return book_list
# 删
def deleteData(id):
book = Books.query.get(id)
# 类似于 select * from Books where id = id
db.session.delete(book)
db.session.commit()
# 提交操作到数据库
# 改
def updateData(id, title='', author='', read='', new_id=''):
book = Books.query.get(id)
if not title=='':
book.title = title
if not author == '':
book.author = author
if not read == '':
book.read = read
if not new_id == '':
book.id=new_id
db.session.commit()
利用我们写好的 增函数 添加数据:
···
insertData('book1','zhangsan',0)
insertData('book2','lisi',1)
···
运行 app.py 后数据就被添加到数据库中。
#Ps:运行后记得在 app.py 中删除上面两句代码
···
from flask import Flask, jsonify, request, make_response
···
···
@app.route('/',methods=['GET','POST'])
def all_books():
response_object = {'status':'success'}
books = selectDataAll()
response_object['books']=books
return jsonify(response_object)
···
一切就绪,我们运行 app.py 就可以在网页中看到数据库中的数据已经被显示出来了:
首先按照下方流程配置所需的应用与环境:
1、我们的电脑中需要 node.js (中文网地址 : http://nodejs.cn/),直接下载安装就OK了( 安装教程 : https://www.runoob.com/nodejs/nodejs-install-setup.html )。
2、安装cnpm( cmd 输入:npm install -g cnpm --registry=http://registry.npm.taobao.org)
3、安装 vue 脚手架 ( cmd 输入:npm install -g vue-cli )
4、安装 webpack( cmd 输入:npm install webpack -g )
5、找到我们先前创建的vue文件夹,cd 进去,cmd 输入 : vue create 文件名 ,接着会出现一个界面:
第一个选项是 过去保存的配置
第二个是默认配置
第三个是自定义(手动选择要素)
我们选择自定义配置 ,小键盘 上下箭头移动,空格是 选中/反选 。
这里我们全选。
然后按回车,进入下一个阶段:
#Ps:注意:最后一条的意思是 :以后的项目是否使用以上配置 (保存配置)
安装完后,我们进入到 vue 根目录下 cmd 中输入 npm run serve
#Ps:如果失败 请检查根目录下的 package.json 文件内容,以及尝试使用 npm run dev 指令启动
启动成功如下图:
到了这一步就差不多接近尾声了,我们通过观察效果图可以得出我们需要的工具有 :
vue:
Flask:
前端安装 axios 后,以 axios.post 这样的方式来处理跨域交互
将以上工具安装完毕后,我们开始最后的工作。
1、修改 flask 文件夹中的 app.py(配置跨域交互) :
···
from flask_cors import CORS # 导入CORS 包
···
···
@app.after_request
def after(resp):
resp = make_response(resp)
resp.headers['Access-Control-Allow-Origin'] = '*' # 允许跨域地址
resp.headers['Access-Control-Allow-Methods'] = '*' # 请求 ‘*’ 就是全部
resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type' # 头部
resp.headers['Access-Control-Allow-Credentials'] = 'True'
return resp
CORS(app, resources=r'/*', supports_credentials=True)
···
2、在vue文件夹下的 src / components 中创建 Alert.vue 文件 以及 Books.vue 文件
3、配置 router / index.js(或者是 index.ts)
import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";
import Books from "../components/Books.vue";
import Home from "../components/HelloWorld.vue";
import 'bootstrap/dist/css/bootstrap.css';
import BootstrapVue from 'bootstrap-vue'
Vue.config.productionTip=false
Vue.use(BootstrapVue);
Vue.use(VueRouter);
const routes: Array = [
{
path: "/home",
name: "Home",
component: Home,
},
{
path: "/", # 将books.vue添加到路由中去
name: "Books",
component: Books,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
export default router;
4、配置 Books.vue 以及 Alert.vue
# Books.vue
Books
{{ message }}
Title
Author
Read?
{{ book.title }}
{{ book.author }}
Yes
No
# Alert.vue
在books.vue 中,我们主要是搭建了网页的基础框架,目前只能获取数据库的数据并显示:
接着,我们开始编写 Add Book 按钮的 代码:
Books
{{ message }}
Title
Author
Read?
{{ book.title }}
{{ book.author }}
Yes
No
Read?
Submit
Reset
以及对应的脚本代码:
修改后端代码(app.py)增加对 POST 请求的 辨别与操作:
···
@app.route('/',methods=['GET','POST','OPTIONS'])
def all_books():
response_object = {'status':'success'}
books = selectDataAll()
if request.method == 'POST':
post_data = request.get_json()
print(post_data)
books_id = post_data.get('id')
del_id = post_data.get('del_id')
title = post_data.get('title'),
author = post_data.get('author'),
read = post_data.get('read')
insertData(
title=title[0],
author=author[0],
read=read
)
response_object['message'] = 'Book added!'
else:
response_object['books']=books
return jsonify(response_object)
···
如法炮制,编写 update 按钮点击事件以及 del 事件
附 Books.vue 全部代码:
Books
{{ message }}
Title
Author
Read?
{{ book.title }}
{{ book.author }}
Yes
No
Read?
Submit
Reset
Read?
Submit
Reset
附后端代码:
from flask import Flask, jsonify, request, make_response
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
app = Flask(__name__)
@app.after_request
def after(resp):
resp = make_response(resp)
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Methods'] = '*'
resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
resp.headers['Access-Control-Allow-Credentials'] = 'True'
return resp
app.config['DEBUG'] = True
CORS(app, resources=r'/*', supports_credentials=True)
# ------------------database----------------------------
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
class Books(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), nullable=False)
author = db.Column(db.String(120), nullable=False)
read= db.Column(db.Boolean)
db.create_all()
# 增
def insertData(title,author,read):
book=Books(title=title,author=author,read=read)
db.session.add_all([book])
db.session.commit()
# 查
def selectDataAll():
book_list=[]
books = Books.query.all()
for s in books:
dic = {}
dic['id'] = s.id
dic['title'] = s.title
dic['author'] = s.author
dic['read'] = s.read
print(f'Id: {s.id} | Title: {s.title} | Author: {s.author} | Read: {s.read}')
print('----')
book_list.append(dic)
return book_list
# 删
def deleteData(id):
book = Books.query.get(id)
db.session.delete(book)
db.session.commit()
# 改
def updateData(id, title='', author='', read='', new_id=''):
book = Books.query.get(id)
if not title=='':
book.title = title
if not author == '':
book.author = author
if not read == '':
book.read = read
if not new_id == '':
book.id=new_id
db.session.commit()
# ------------------database---end----------------------
@app.route('/',methods=['GET','POST','OPTIONS'])
def all_books():
response_object = {'status':'success'}
books = selectDataAll()
if request.method == 'POST':
post_data = request.get_json()
print(post_data)
books_id = post_data.get('id')
del_id = post_data.get('del_id')
if books_id == 'null' and del_id == 'null':
title = post_data.get('title'),
author = post_data.get('author'),
read = post_data.get('read')
insertData(
title=title[0],
author=author[0],
read=read
)
response_object['message'] = 'Book added!'
elif (not books_id == 'null') and del_id == 'null':
put_data = post_data
books_id = put_data.get('id')
title = put_data.get('title')
author = put_data.get('author')
read = put_data.get('read')
updateData(
id=books_id,
title=title,
author=author,
read=read
)
response_object['message'] = 'Book update!'
else:
deleteData(del_id)
response_object['message'] = 'Book del!'
else:
response_object['books']=books
books = selectDataAll()
for i in range(len(books)):
id=books[i]['id']
updateData(id=id,new_id=i+1)
print(response_object)
return jsonify(response_object)
if __name__ == '__main__':
app.run(port=5000,debug=True)
至此结束,码字辛苦,还请各位哥哥姐姐留个赞再走呗,先谢谢了嗷~!