之前快速上手中创建的app.py的文件便可以删除,亦或者你重新创建一个项目开始以下的内容,建议是新建一个目弯宴孙录来开始我们以下的内容!
在实际开发过程中,一个完整的项目一定是由多个不同的功能模块构成,以我们的埋链博客系统为例,主要由两个大的功能模块构成,一个是负责用户认证以及用户权限 *** 作的模块auth, 一个则是我们博客的主应用模块blog,他主要负责博客的内容/分类等一些与博客相关的功能!
为了实现以上需求,我们就需要现在虚拟环境venv的同级目录新建一个app的目录,用这个目录来统一管理各功能模块,并在其内部分别新建auth和blog目录,结构如下所示!
从以上目录可以看出,我们在每一个文件夹下都内置了一个__init__.py的文件,使其变成一个可互相调用的模块!
为了区别app目录和RealProject目录,我们将分别称起名为应用目录(app) , 项目目录(RealProject) ,在以后的教程中出现对应的字眼请自行甄别和区分!
在app的同级我们创建一个 RealProject 的目录,并分别在其内部创建 __init__.py 、 settings.py 、 wsgi.py 三个文件, 目录结构如下:
最后,我们将创建一个manage.py入口文件作为我们整个项目的入口,最后我们只需要运行该文件即可启动我们的项目!
最后,我们完整的目录结构如下所示:
熟悉django的同学肯定会对这个目录结构不会陌生,本目录结构本身也就是参照django的目录结构来构造!
import os
config="""
import os
basedir = os.path.abspath(os.path.dirname( file ))
class Config:
SECRET_KEY ='hard to guess string'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
FLASKY_MAIL_SUBJECT_PREFIX = '[Flasktest]'
FLASKY_MAIL_SENDER = ' 13285921108@163.com '
FLASKY_ADMIN = 'huangat'
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG = True
MAIL_SERVER = 'mail.163.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = os.environ.get('13285921108')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
"""
manage="""
import os
from app import create_app, db
from app.models import User, Role
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
app = create_app('default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if name == ' main ':
manager.run()
"""
models="""
class User:
pass
class Role:
pass
"""
email="""
from threading import Thread
from email import charset
from flask_mail import Message
from flask import render_template
from flask import current_app# 这样就不用使用from manager import app
from . import mail
charset.add_charset('utf-8', charset.SHORTEST, charset.BASE64, 'utf-8')
def send_async_mail(app, msg):
with app.app_context():
mail.send(msg)
def send_mail(receiver, subject, template, **kw):
app = current_app._get_current_object()
msg = Message(subject=subject, sender=app.config[
'FLASKY_MAIL_SENDER'], recipients=[receiver], charset='utf-8')
msg.body = render_template(template + '.txt', **kw)
msg.html = render_template(template + '.html', **kw)
thr = Thread(target=send_async_mail, args=[app, msg])
thr.start()
return thr
"""
init="""
from os import path
from flask import Flask, request
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_moment import Moment
from werkzeug.routing import BaseConverter
from config import config
class RegexConverter(BaseConverter):
bootstrap = Bootstrap()
db = SQLAlchemy()
login_manager = LoginManager()
mail = Mail()
moment = Moment()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login' # login_view设置登陆页面的端点
basedir = path.abspath(path.dirname( file ))
def create_app(config_name):
app = Flask( name )
app.config.from_object(config[config_name])
config[config_name].init_app(app)
"""
maininit="""
from flask import Blueprint
main = Blueprint('main', name )
from . import views, errors
"""
errors="""
from flask import render_template
from . import main
@main.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@main.app_errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
"""
forms="""
class NameForm:
pass
"""
views="""
from datetime import datetime
from flask import render_template, session, redirect, url_for
from . import main
from .forms import NameForm
from .. import db
from ..models import User
@main.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
# ...
return redirect(url_for('main.index'))
return render_template('index.html',form=form, name=session.get('name'),known=session.get('known', False),current_time=datetime.utcnow())
"""
def main():
os.mkdir("app")
os.mkdir("app\main")
os.mkdir("app\static")
os.mkdir("app\templates")
os.mknod("app\templates\404.html")
os.mknod("app\templates\500.html")
os.mknod("app\templates\index.html")
os.mkdir("tests")
os.mkdir("venv")
os.mkdir("migrations")
os.mknod("requirements.txt")
os.mknod("tests_ init .py")
with open("config.py","w") as f:
f.write(config)
with open("manage.py","w") as f:
f.write(manage)
with open("app\models.py","w") as f:
f.write(models)
with open("app\email.py","w") as f:
f.write(email)
with open("app_ init .py","w") as f:
f.write(init)
with open("app\main_ init _.py","w") as f:
f.write(maininit)
with open("app\main\errors.py","w") as f:
f.write(errors)
with open("app\main\forms.py","w") as f:
f.write(forms)
with open("app\main\views.py","w") as f:
f.write(views)
main()
1、首先了解什么是 restful 架构?
rest :representational state transfer表现层状态转化
资源 :网络上的一个实体,或者说一个具体的信息。每种资源对应一个特定的URI,要获取这个资源,就是访问这个URI就可以
表现层 :representation 把资源呈现出来的形式,叫做表现层,在HTTP请求的头信息中用Accept和Content-Type字段指定,是对“表现层”的裤升描述
状态转化 :客户端想要 *** 作服务器,必须通过某种手段,让服务器发生状态转化,有 GET 、 POST 、 PUT 、 DELETE 四种方式,其中 GET 是用来获取资源, POST 是用来新建资源(也可以进行更新资源), PUT 用来更新资源, DELETE 用来删除资源
所以restful架构是:
1)每一个URI代表一个资源;
2)客户端和服务器之间,传递这种资源的某种表现层;
3)客户端通过四个HTTP动词,对服务器端资源进行 *** 作,实现“表现层状态转化”;
误区:最常见的一种设计错误,就是URI中包含动词。因为“资源”表示一种实体,所以应该是名词,URI不应该有动词,动词应该放到HTTP协议中
2、Flask-RESTful基本请求
其中一个接口有两种请求方式,一个是get,另一个是post。
get返回USER_LIST这个json数据;
post需要传一个参数,然后返回整个USER_LIST,请求一次post方法就会多添加一次数据,如果post请求中找不到name字段,则返回“400 Bad Request”错误;
由于类UserList没有定义put()和delete()函数,所以在”PUT”或”DELETE”请求时会返回”405 Method Not Allowed”世缺错误。
其中在postman中是这么胡返老进行传递的
GET请求
POST请求
另外,路由支持多个路径,比如:
访问userlist和users两个路径的效果完全一样
3、带参数的请求
上面的例子中我们都是针对USER_LIST这个列表的,如果我们需要针对具体的user进行 *** 作呢,就需要传递具体的user_id了,这时候,我们就需要路由支持带参数。
在User类的get(),post(),put()等成员函数中,记得加上参数user_id来获取传入的变量值
4、参数解析
在“POST”和“PUT”请求中,直接访问form表单并验证的工作有些麻烦,Flask-RESTful提供了 reqparse库来简化,可以通过 parser.add_argument() 方法来定义form表单字段,并指定其类型,然后在put或者post函数中调用 parser.parse_args() 来获取表单内容,并返回一个字典,该字典就包含表单的内容。 parser.parse_args() 方法会自动验证数据类型,返回400错误,还可以添加strict参数,如 parser.parse_args(strict=True) ,此时出现为定义的参数,也会返回400错误
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)