pythonflask分页前后端分离_详解Flask前后端分离项⽬案例简介
学习慕课课程,Flask前后端分离API后台接⼝的实现demo,前端可以接⼊⼩程序,暂时已经完成后台API基础架构,使⽤ postman 调试.git
重构部分:
ken校验模块
auths认证模块
scope权限模块,增加全局扫描器(参考flask HTTPExceptions模块)
收获
我们可以接受定义时的复杂,但不能接受调⽤时的复杂
如果你觉得写代码厌倦,⽆聊,那你只是停留在功能的实现上,功能的实现很简单,你要追求的是更好的写法,抽象的艺术,不是机械的劳动⽽是要 创造 ,要有⾃⼰的思考
Sqlalchemy 中对类的创建都是⽤元类的⽅式,所以调⽤的时候都不⽤实例化,当我们重写 __init__ ⽅法
是需要调⽤ strcut 装饰器,才会执⾏实例化对象的构造函数
权限等级模块的设计( api访问权限 ),如超级管理员,管理员,普通⽤户,访客,这四者之间的关系,有包含的关系,所以可以考虑合并也可以考虑排除的⽅式来构建权限控制模块. 参考本项⽬中的 app.libs.scope
学的是解决问题的⽅法,⾸先要有深度,在去考虑⼴度,还要懂得迁移应⽤,形成⾃⼰的思维模型。
知识点复盘
初始化flask应⽤程序
app = Flask(__name__, static_folder='views/statics', static_url_path='/static', template_folder="templates")
创建Flask应⽤程序实例对象, 如果模块存在,会根据模块所在的⽬录去寻静态⽂件和模块⽂件, 如果模块不存在,会默认使⽤app对象所在的项⽬⽬录
__name__ 表⽰以此模块所在的⽬录作为⼯作⽬录,就是静态⽂等从这个⽬录下去
static_folder 指定静态⽂件存放相对路径 flask默认会⽤/进⾏分割然后取最后⼀个作为访问 url 类似 Django 中的 STATICFILES_DIRS
static_url_path 指定访问静态⽂件的 url 地址前缀, 类似 Django 中的 STATIC_URL
template_folder 指定模板⽂件的⽬录
asp网站源码域名授权破解
@property
def static_url_path(self):
"""The URL prefix that the static route will be accessible from.
If it was not configured during init, it is derived from
:attr:`static_folder`.
"""
if self._static_url_path is not None:
return self._static_url_path
if self.static_folder is not None:
basename = os.path.basename(self.static_folder)
return ("/" + basename).rstrip("/")
@static_url_path.setter
def static_url_path(self, value):
if value is not None:
value = value.rstrip("/")
self._static_url_path = value
Flask 中 url 相关底层类
BaseConverter ⼦类:保存提取 url 参数匹配规则
Rule 类:记录⼀个 url 和⼀个视图函数的对应关系
Map 类:记录所有 url 地址和试图函数对应的关系 Map(Rule, Rule, ....)
MapAdapter 类:执⾏ url 匹配的过程,其中有⼀个 match ⽅法, Rule.match(path, method)⾃定义路由管理器
from flask import Flask
app = Flask(__name__)
uting import BaseConverter
class RegexUrl(BaseConverter):
# 指定匹配参数时的正则表达式
# 如: # regex = '\d{6}'
def __init__(self, url_map, regex):
"""
:param url_map: flask会⾃动传递该参数
:param regex: ⾃定义的匹配规则
"""
super(RegexUrl, self).__init__(url_map)
< = regex
# 在对应的试图函数之前调⽤
# 从url中提取出参数之后,会先调⽤to_python
# 会把提取出的值作为参数传递给to_pthon在返回给对应的试图
def to_python(self, value):
"""可以在这⾥做⼀些参数的类型转换"""
return value
# 调⽤url_for时会被调⽤, ⽤来处理url反向解析时url参数处理
# 返回值⽤来拼接url
def to_url(self, value):
"""对接收到参数做⼀些过滤等"""
return value
# 将⾃定义路由转换器类添加到转换器字典中
app.verters['re'] = RegexUrl
# 案例
@ute('/user/')
def hello(id):
return f'hello {id}'
if __name__ == '__main__':
app.run(debug=True)
全局异常捕获
AOP编程思想,⾯向切⾯编程,把事件统⼀在⼀个地⽅处理,在⼀个统⼀的出⼝做处理
errorhandler 在flask 1.0版本之前只⽀持填写对应的错误码,⽐如 @handler(404)
在flask1.0版本之后就⽀持全局的异常捕获了 @handler(code_or_exception) ,有了这个之后,就可以在全局做⼀个异常捕获了,不⽤每个视图函数都做异常捕获。
@handler(Exception)
def framework_error(e):
if isinstance(e, APIException):
javaapp联网
return e
elif isinstance(e, HTTPException):
code = e.code
msg = e.description
error_code = 1007
return APIException(msg, code, error_code)
else:
if not fig['DEBUG']:
return ServerError()
else:
raise e
异常类型
可预知的异常(已知异常)
完全没有意识的异常(未知异常)
abort函数
abort(状态码) 是⼀个默认的抛出异常的⽅法
调⽤abort函数可以抛出⼀个指定状态码对应的异常信息
abort函数会⽴即终⽌当前视图函数的运⾏**
模型对象的序列化
场景:我们有时候可能需要返回模型对象中的某些字段,或者全部字段,平时的做法就是将对象中的各个字段转为字典在返回
jsonnify(data) , 但是这样的写法可能在每个需要返回数据的试图函数中都写⼀个对应的字典。。对象转字典在返回。 json 默认是不能序列化对象的,⼀般我们的做法是 json.dumps(obj, default=lambda o: o.__dict__) 但是 __dict__ 中只保存实例属性,我们的模型类基本定义的类属性。解决这个问题就要看 jsonify 中是如何做序列化的,然后怎么重写。
重写 JSONEncoder
from datetime import date
from flask import Flask as _Flask
from flask.json import JSONEncoder as _JSONEncoder
class JSONEncoder(_JSONEncoder):
"""
重写json序列化,使得模型类的可序列化
"""
def default(self, o):
if hasattr(o, 'keys') and hasattr(o, '__getitem__'):
return dict(o)
if isinstance(o, date):
return o.strftime('%Y-%m-%d')
super(JSONEncoder, self).default(o)
# 需要将重写的类绑定到应⽤程序中
class Flask(_Flask):
json_encoder = JSONEncoder
模型类的定义
class User(Base):
id = Column(Integer, primary_key=True)
email = Column(String(24), unique=True, nullable=False)
nickname = Column(String(24), unique=True)
xordel官方auth = Column(SmallInteger, default=1)
_password = Column('password', String(100))
def keys(self):
return ['id', 'email', 'nickname', 'auth']
def __getitem__(self, item):
return getattr(self, item)
数据结构replace函数注意: 修改了 json_encode ⽅法后,只要调⽤到 flask.json 模块的都会⾛这个⽅法
为什么要写 keys 和 __getitem__ ⽅法
当我们使⽤ dict(object) 操作⼀个对象的时候, dict ⾸先会到实例中 keys 的⽅法,将其返回列表的值作为 key , 然后会根据
object[key] 获取对应的值,所以实例要实现 __getitem__ ⽅法才可以使⽤中括号的⽅式调⽤属性
进阶写法- 控制返回的字段
场景:当我们有⼀个 Book 的模型类,我们的 api 接⼝可能需要返回 book 的详情页所以就要返回所有字典,但另外⼀个接⼝可能只需要返回某⼏个字段。
class Book(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(50), nullable=False)
author = Column(String(30), default='未名')
binding = Column(String(20))
publisher = Column(String(50))
price = Column(String(20))
pages = Column(Integer)
pubdate = Column(String(20))
isbn = Column(String(15), nullable=False, unique=True)
summary = Column(String(1000))
image = Column(String(50))
# orm实例化对象, 字段需要写在构造函数中,这样每个实例对象都会有⾃⼰的⼀份,删除增加都不会互相影响
@structor
def __init__(self):
self.fields = ['id', 'title', 'author', 'binding',
'publisher', 'price', 'pages', 'pubdate',
'isbn', 'summary', 'image']
def keys(self):
return self.fields if hasattr(self, 'fields') else []
def hide(self, *keys):
for key in keys:
结构体数组动态分配内存
ve(key)
return self
def append(self, *keys):
for key in keys:
self.fields.append(key)
python3基础教程慕课版电子版
return self

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。