在上一篇博客里讲解了如何应用 route decorator 和 pagination, 点击这里查看
现在就提供一些例子来做个demo
文件结构:
example
| models.py
|--flaskr
| | __init__.py
前提是,得在本地创建postgre数据库,可以查看如何创建数据库
所使用的数据为:
现在提供models.py
# models.py
# 版权所有
import os
from sqlalchemy import Column, String, Integer, Boolean, create_engine
from flask_sqlalchemy import SQLAlchemy
import json
from sqlalchemy.sql.schema import PrimaryKeyConstraint
import psycopg2
database_name = "plants"
database_path = 'postgres://username@localhost:5432/plants'
# database_path = "postgresql://{}:{}@{}/{}".format(
# "postgres", "", "localhost:5432", database_name
# )
db = SQLAlchemy()
def setup_db(app, database_path=database_path):
app.config["SQLALCHEMY_DATABASE_URI"] = database_path
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.app = app
db.init_app(app)
db.create_all()
class Plant(db.Model):
__tablename__ = 'plants'
id = Column(Integer, primary_key=True)
name = Column(String)
scientific_name = Column(String)
is_poisonous = Column(Boolean)
primary_color = Column(String)
def __init__(self, name, scientific_name, is_poisonous, primary_color):
self.name = name
self.scientific_name = scientific_name
self.is_poisonous = is_poisonous
self.primary_color = primary_color
def insert(self):
db.session.add(self)
db.session.commit()
def update(self):
db.session.commit()
def delete(self):
db.session.delete(self)
db.session.commit()
def format(self):
return {
"id": self.id,
"name": self.name,
"scientific_name": self.scientific_name,
"is_poisonous": self.is_poisonous,
"primary_color": self.primary_color
}
现在提供**init.py**
# __init__.py
# 版权所有
from flask import Flask, jsonify, request, abort
from models import setup_db, Plant
from flask_cors import CORS
def create_app(test_config=None):
app = Flask(__name__)
setup_db(app)
# Resource Specific Usage
# cors(app, resources={r"*/api/*": {origins: '*}})
# Basic Initialization
CORS(app)
@app.after_request
def after_request(response):
# Content-Type: ensure that this is allowed that we can specify what is the content
# and respond with how the client should actually use that content and authorization.
response.headers.add('Access-Control-Allow-Headers', 'Content-Type, Authorization')
# Specify all of the methods that plan to use or have this app respond to
response.headers.add('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, OPTIONS')
return response
@app.route("/plants", methods=['GET','POST'])
# @cross_origin
def get_plants():
# Implement pagnitation
page = request.args.get("page", 1, type=int)
start = (page-1) * 10
end = start + 10
plants = Plant.query.all()
formatted_plants = [plant.format() for plant in plants]
return jsonify(
{
"success": True,
"plants": formatted_plants[start:end],
"total_plants": len(formatted_plants)
}
)
# @app.route("/plants/<int:plant_id>")
def get_specific_plant(plant_id):
plant = Plant.query.filter(Plant.id == plant_id).one_or_none()
if plant is None:
abort(404)
else:
return jsonify({
"success": True,
"plant": plant.format()
})
return app
现在来运行这个程序,来测试这个API能不能用
- 在Terminal里
$ cd example
$ export FLASK_APP=flaskr
$ export FLASK_ENV=development
$ flask run
- 运行结果会给你一个地址,这时候,可以用curl这个地址
$ curl http://example.url:exampleport/
结果会是
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
为什么会这样呢?因为在程序里,没有写
@app.route(’/’)
所有这个结果是正确的
- 当curl的地址是这样的
$ curl http://example.url:exampleport/plants
结果会是:
{
"plants": [
{
"id": 1,
"is_poisonous": true,
"name": "Hydrangea",
"primary_color": "blue",
"scientific_name": "Hydrangea macrophylla"
},
{
"id": 2,
"is_poisonous": true,
"name": "Oleander",
"primary_color": "pink",
"scientific_name": "Nerium oleander"
},
{
"id": 3,
"is_poisonous": true,
"name": "Water Hemlock",
"primary_color": "white",
"scientific_name": "Cicuta"
},
{
"id": 4,
"is_poisonous": false,
"name": "Bamboo",
"primary_color": "green",
"scientific_name": "Bamboosa aridinarifolia"
},
{
"id": 5,
"is_poisonous": false,
"name": "Carrot",
"primary_color": "orange",
"scientific_name": "Daucas carota"
},
{
"id": 6,
"is_poisonous": false,
"name": "Lemon",
"primary_color": "yellow",
"scientific_name": "Citrus limonium"
},
{
"id": 7,
"is_poisonous": true,
"name": "Foxglove",
"primary_color": "purple",
"scientific_name": "Digitalis"
},
{
"id": 8,
"is_poisonous": true,
"name": "Lily of the Valley",
"primary_color": "white",
"scientific_name": "Convallaria majalis"
},
{
"id": 9,
"is_poisonous": true,
"name": "Dieffenbachia",
"primary_color": "green",
"scientific_name": "Dieffenbachia seguine"
},
{
"id": 10,
"is_poisonous": false,
"name": "Tomato",
"primary_color": "red",
"scientific_name": "Lycopersican esculentum"
}
],
"success": true,
"total_plants": 12
}
因为在代码里,只显示10个数据,所有这个结果是正确的。
- 要想测试curl获得具体的plant, 比如说想了解plant id = 2, 可以这样
$ curl http://example.url:exampleport/plants/2
结果:
{
"plant": {
"id": 2,
"is_poisonous": true,
"name": "Oleander",
"primary_color": "pink",
"scientific_name": "Nerium oleander"
},
"success": true
}
- 如果查询具体的plant没有在数据库里,就会报错
$ curl http://example.url:exampleport/plants/20
结果:
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>