简介
学习慕课课程,Flask前后端分离API后台接口的实现demo,前端可以接入小程序,暂时已经完成后台API基础架构,使用 postman 调试.git
重构部分:
收获
知识点复盘
初始化flask应用程序
app = Flask(__name__, static_folder='views/statics', static_url_path='/static', template_folder="templates")
创建Flask应用程序实例对象, 如果模块存在,会根据模块所在的目录去寻找静态文件和模块文件, 如果模块不存在,会默认使用app对象所在的项目目录
@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 相关底层类
自定义路由管理器
from flask import Flask app = Flask(__name__) from werkzeug.routing 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) self.regex = 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.url_map.converters['re'] = RegexUrl # 案例 @app.route('/user/<re("[a-z]{3}"):id>') def hello(id): return f'hello {id}' if __name__ == '__main__': app.run(debug=True)
全局异常捕获
AOP编程思想,面向切面编程,把事件统一在一个地方处理,在一个统一的出口做处理
errorhandler 在flask 1.0版本之前只支持填写对应的错误码,比如 @app.errorhandler(404)
在flask1.0版本之后就支持全局的异常捕获了 @app.errorhandler(code_or_exception) ,有了这个之后,就可以在全局做一个异常捕获了,不用每个视图函数都做异常捕获。
@app.errorhandler(Exception) def framework_error(e): if isinstance(e, APIException): return e elif isinstance(e, HTTPException): code = e.code msg = e.description error_code = 1007 return APIException(msg, code, error_code) else: if not current_app.config['DEBUG']: return ServerError() else: raise e
异常类型
模型对象的序列化
场景:我们有时候可能需要返回模型对象中的某些字段,或者全部字段,平时的做法就是将对象中的各个字段转为字典在返回 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) 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)
注意: 修改了 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实例化对象, 字段需要写在构造函数中,这样每个实例对象都会有自己的一份,删除增加都不会互相影响 @orm.reconstructor 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: self.fields.remove(key) return self def append(self, *keys): for key in keys: self.fields.append(key) return self @api.route('/search') def search(): books = Book.query.filter().all() # 根据某些条件搜索的 books = [book.hide('summary') for book in books] return jsonify(books) @api,route('/<isbn>/detail') def detail(isbn): book = Book.query.filter_by(isbn=isbn).first_or_404() return jsonify(book)
请求钩子函数
全局扫描器
模仿flask exceptions 预加载各个异常类的方式,将用户组自动加载进内存中,这样获取的话就更方便
str2obj = {} level2str = {} def iteritems(d, *args, **kwargs): return iter(d.items(*args, **kwargs)) def _find_scope_group(): for _name, obj in iteritems(globals()): try: is_scope_obj = issubclass(obj, BaseScope) except TypeError: is_scope_obj = False if not is_scope_obj or obj.level < 1: continue old_obj = str2obj.get(_name, None) if old_obj is not None and issubclass(obj, old_obj): continue str2obj[_name] = obj level2str[obj.level] = _name # 模仿flask exceptions 预加载各个异常类的方式,将用户组自动加载进内存 _find_scope_group() del _find_scope_group
常见bug
form 正则校验注意事项
r'{6, 25}$'
带空格和不带空格是两码事, 正则里面{,} 连续不带空格
r'{6,25}$'
参考
Python Flask高级编程之RESTFul API前后端分离精讲
到此这篇关于详解Flask前后端分离项目案例的文章就介绍到这了,更多相关Flask前后端分离 内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
前后端分离 在B/S架构的环境中,前后端分离一直都众说纷纭,没有一个标准。我觉得打开可以分为三个阶段: 传统的分离方法 传统意义上的前后端分离,前端指的是美工、切图、设计,后端是实现代码、数据库相关的实现。美工设计和生成的前端页面,给到程序员来做集成。那么这里其实就不分什么前后端了,程序员从数据库一直搞到前端页面的样式,就是“全能型运动员“。当然,一般传统上的开发协作模式有两种: 一种是前端先写一
本文向大家介绍vue2 前后端分离项目ajax跨域session问题解决方法,包括了vue2 前后端分离项目ajax跨域session问题解决方法的使用技巧和注意事项,需要的朋友参考一下 最近学习使用vuejs前后端分离,重构一个已有的后台管理系统,遇到了下面这个问题: 实现跨域请求时,每次ajax请求都是新的session,导致无法获取登录信息,所有的请求都被判定为未登陆。 1、 vuejs a
这是一个前后端分离的项目:前端是React,后端是Node.js 本地测试没有任何问题,上传到云服务器之后,测试后端没有任何问题。但是React却无法把数据发给后端 网上查询用Nginx部署前端,我的nginx核心配置文件如下 外网访问http://www.xiaoyangst.top能够看到前端,说明nginx配置没有问题,但是代理配置应该存在问题,即跨域问题 本地测试环境跨域问题没有,因为可以
前言 上一篇我们遇到'少年,是不是忘了npm run mock?'的警告,这一篇我们就来解决这个问题。 开发 一、安装包 安装koa和一系列的包(我们用的是koa v2): koa koa-bodyparser koa-router boom nodemon mockjs 解释说明一下(知道的同学可以忽略): 名称 作用 koa 我们都知道Node.js有HTTP模块,来处理HTTP请求
本文向大家介绍node vue项目开发之前后端分离实战记录,包括了node vue项目开发之前后端分离实战记录的使用技巧和注意事项,需要的朋友参考一下 前言 本文主要介绍了关于node vue前后端分离的相关资料,分享出来供大家参考学习,下面随着小编来一起学习学习吧。 node vue项目开发 最近看了近一周的vue开发,有诸多感触,我之前接触过react、angular所以特别想学学久仰大名的v
很奇怪 使用nginx+docker部署的前后端分离项目 部署上去之后访问的时候出现空白也没有报错,然后按照网上的教程,改了vue的配置文件。也没有效果,不管前面加了点还是没加就是出现不了页面,都是空白的 不知道是什么导致了 很迷茫 有懂的吗 帮忙解决一下呗! 改了vue的打包配置 不管是加了点还是没加都显示不出页面