上一篇文章,介绍了前后端分离开发环境的搭建。环境准备好之后,我们可以从后端入手开发业务接口。也可以从前端入手,开发相关页面与业务功能。开发顺序没有先后之分,完全取决于你的喜好。我喜欢从后端开始。
首先,在api目录下激活Python虚拟开发环境,安装以下Flask扩展包和第三包。
$(venv) pip install flask-sqlalchemy $(venv) pip install pymysql
数据库配置
现在,我们准备好了程序所需的所有东西。打开api.py文件,添加如下程序代码::
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///books.db'app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb = SQLAlchemy(app)
创建数据模型
上述程序是做了数据库相关的配置,你可以根据实际情况,做一些调整。继续在api.py文件中编写书籍作者数据模型程序程序。
# 作者信息模型class Author(db.Model): id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(20)) specialisation = db.Column(db.String(50)) def __init__(self,name,specialisation): self.name = name self.specialisation = specialisation def __repr__(self): rturn '' % self.id
模型编写好以后,需要在数据库建立对应的数据结构,这样数据才可以存储和操作。在开发一个应用的过程中,数据模型的改动非常频繁,如果是纯手动去维护数据库的数据结构,是一件非常低效的事情。这里介绍一种高效方法,首先安装如下Flask扩展包。
$(venv) pip install flask-migrate
flask-migrate可以帮助我们自动化完成数据模型到数据库的操作。继续打开api.py文件添加相关程序。
from flask_migrate import Migrate # 添加到程序开始导包的地方migrate = Migrate(app,db) # 添加到db = SQLAlchemy(app)后面
数据库迁移
程序编写成,保存后。我们继续在命令行执行下面的命令,即可在数据库中看到作者信息表了。
$(venv) flask db init # 初始化操作$(venv) flask db migrate # 数据库迁移操作
运行完这两个命令后,在当前的目录下会生成一个books.db文件,我这里使用的是sqlite数据库。当然也可以把数据库改成mysql,都一样的。另外如果你的数据模型有改变,需要执行下面这个命令,进行升级操作。
$(venv) flask db upgrade # 数据模型升级操作
为了使用SQLAlchemy返回的数据从接口中返回JSON格式数据,我们需要另一个名为marshmallow的库,它是SQLAlchemy的附加组件,用于将SQLAlchemy返回的数据对象序列化为JSON。
数据序列化
我们通过如下命令,继续安装flask-marshmallow第三方扩展库。
(venv)$ pip install flask-marshmallow(venv)$ pip install marshmallow-sqlalchemy
继续打开api.py文件添加相关程序,具体需要新添加的程序是如下方这样。
from marshmallow_sqlalchemy import ModelSchema from marshmallow import fields# 序列接口数据为JSON格式class AuthorSchema(ModelSchema): class Meta(ModelSchema.Meta): model = Author sqla_session = db.session id = fields.Number(dump_only=True) name = fields.String(required=True) specialisation = fields.String(required=True)
编写为AuthorSchema之后,我们就可以创建接口了。让我们从第一个获取作者信息的接口开始。这个接口返回所有注册的作者信息。
获取所有作者信息
继续打开api.py文件,编写查询作者信息接口,具体接口程序如下:
@app.route('/authors',methods=['GET'])def get_authors(): get_authors = Author.query.all() author_schema = AuthorSchema(many=True) authors,error = author_schema.dump(get_authors) return make_response(jsonify({"authors":authors}))
在这个方法中,我们将获取数据库中的所有作者信息,将其转储到AuthorSchema中,并以JSON形式返回结果。启动flask服务,并在浏览器中访问http://127.0.0.1:5000/authors,正常情况下,可以看到如下结果。
创建作者信息
现在让我们继续开发一个添加作者信息的接口。首先在作者数据模型程序中,添加创建作者信息的方法。具体程序如下:
def create(self): db.session.add(self) db.session.commit() return self
上面的方法使用该数据创建一个新对象,然后返回创建的对象。现在你的Author类应该是下面这样的:
class Author(db.Model): id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(20)) specialisation = db.Column(db.String(50)) def create(self): db.session.add(self) db.session.commit() return self def __init__(self,name,specialisation): self.name = name self.specialisation = specialisation def __repr__(self): return '' % self.id
现在我们编写添加作者信息的接口程序,在获取作者信息接口后面,继续编写以下代码:
@app.route('/authors',methods=['POST'])def create_author(): data = request.get_json() author_schema = AuthorSchema() authors = author_schema.load(data) result = author_schema.dump(authors.create()).data return make_response(jsonify({"author":result}),201)
上面的方法将获取JSON请求数据,将数据加载到marshmallow模式中,然后调用我们在Author类中创建的create方法,该方法将返回已创建的带有201状态码的对象。
我们可以使用postman对这个接口进行调试和测试。看看我们的接口是否功能正常。具体测试结果,是下图这样的。
现在,如果我们使用获取作者信息接口,进行查询,将会获得新添加的作者信息。
获取指定作者信息
到目前为止,我们已经实现了创建新的作者和获取作者信息接口。接下来,我们将实现一个使用作者ID查询作者信息的接口。上面获取作者信息的接口,是一个所有作者信息的接口。在获取所有作者信息方法下面,继续编写通过作者ID获得作者信息接口。
@app.route('/authors/',methods=['GET'])def get_author_by_id(id): get_author = Author.query.get(id) author_schema = AuthorSchema() author = author_schema.dump(get_author) return make_response(jsonify({"author":author}))
接下来,我们需要测试这个接口,我们将请求ID为1的作者,正如我们在前面看到的那样,获取所有作者API响应,因此,让我们再次打开Postman并在我们的应用服务器上请求/authors/1来检查响应结果是否正确。
更新作者信息
接下来,我们继续编写更新作者信息接口。更新作者信息我们是通过PUT方法来完成的。打开api.py文件,继续编写更新作者信息代码。
@app.route('/authors/',methods=['PUT'])def update_author_by_id(id): data = request.get_json() get_author = Author.query.get(id) if data.get('specialisation'): get_author.specialisation = data['specialisation'] if data.get('name'): get_author.name = data['name'] db.session.add(get_author) db.session.commit() author_schema = AuthorSchema(only=['id','name','specialisation']) author = author_schema.dump(get_author) return make_response(jsonify({"author":author}))
继续打开postman,使用PUT方法请求接口http://127.0.0.1:5000/authors/1,测试接口。详细接口见下图。
删除接口开发
现在,从数据库中删除作者信息是我们的最后一个接口。编写以下代码来实现一个删除接口。
@app.route('/authors/',methods=['DELETE'])def delete_author_by_id(id): get_author = Author.query.get(id) db.session.delete(get_author) db.session.commit() return make_response({"msg":"ok"},204)
最后一个删除接口,你可以使用postman进行测试。删除之后,再调用查询接口,查看结果。
以上就是我们使用Flask框架实现的增删查改接口,还有很多地方需要优化和改进,后续文章中,将逐步将其完善。
完整程序清单
import timefrom flask import Flask,request, jsonify, make_responsefrom flask_cors import CORSfrom flask_sqlalchemy import SQLAlchemyfrom flask_migrate import Migratefrom marshmallow_sqlalchemy import ModelSchemafrom marshmallow import fieldsapp = Flask(__name__)#app.config['SQLALCHEMY_DATABASE_URL'] = 'mysql+pymysql://:@:/'app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///books.db'app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb = SQLAlchemy(app)migrate = Migrate(app,db)CORS(app)# 建立作者模型class Author(db.Model): id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(20)) specialisation = db.Column(db.String(50)) def create(self): db.session.add(self) db.session.commit() return self def __init__(self,name,specialisation): self.name = name self.specialisation = specialisation def __repr__(self): return '' % self.idclass AuthorSchema(ModelSchema): class Meta(ModelSchema.Meta): model = Author sqla_session = db.session id = fields.Number(dump_only=True) name = fields.String(required=True) specialisation = fields.String(required=True)@app.route('/authors',methods=['GET'])def get_authors(): get_authors = Author.query.all() author_schema = AuthorSchema(many=True) authors = author_schema.dump(get_authors) return make_response(jsonify({"authors":authors}))@app.route('/authors/',methods=['GET'])def get_author_by_id(id): get_author = Author.query.get(id) author_schema = AuthorSchema() author = author_schema.dump(get_author) return make_response(jsonify({"author":author}))@app.route('/authors',methods=['POST'])def create_author(): data = request.get_json() author_schema = AuthorSchema() authors = author_schema.load(data) result = author_schema.dump(authors.create()) return make_response(jsonify({"author":result}),201)@app.route('/authors/',methods=['PUT'])def update_author_by_id(id): data = request.get_json() get_author = Author.query.get(id) if data.get('specialisation'): get_author.specialisation = data['specialisation'] if data.get('name'): get_author.name = data['name'] db.session.add(get_author) db.session.commit() author_schema = AuthorSchema(only=['id','name','specialisation']) author = author_schema.dump(get_author) return make_response(jsonify({"author":author}))@app.route('/authors/',methods=['DELETE'])def delete_author_by_id(id): get_author = Author.query.get(id) db.session.delete(get_author) db.session.commit() return make_response({"msg":"ok"},204)@app.route('/time')def get_current_time(): return {'time': time.time()}
上面是这次实战的完整程序清单,可以直接拿来使用。本次内容介绍至此完。