python网站开发实例 flask_使用flask搭建web项目框架实例分享

概要

好久没有碰flask框架了,近期写点东西,回忆一下,分享小伙伴入门flask,并分享源代码,见文章底部

拓展flask支持banner, 支持config.properties配置文件导入

模块化设计,支持数据库迁移

封装sqlalchemy数据库操作

自动转json

配置拦截器,异常自动解析(web请求返回错误页面,curl请求返回错误json)

拓展flask内置函数,支持环境变量

集成celery框架异步处理

支持docker构建

flask jinja2模板示例

swagger api文档配置

等等

模块结构图

.

.

├── banner.txt

├── bootstrap_app.py

├── bootstrap_celery.py

├── config.properties

├── config.py

├── Dockerfile

├── examples

│   ├── extensions_flask_form.py

│   ├── extensions_flask_SQLAlchemy.py

│   ├── hello_world.py

│   ├── index.py

│   ├── __init__.py

│   └── rest_api.py

├── flaskapp

│   ├── common

│   │   ├── error_view.py

│   │   ├── exceptions.py

│   │   ├── __init__.py

│   │   ├── logger.py

│   │   ├── response.py

│   │   ├── tools.py

│   │   └── utils.py

│   ├── core

│   │   ├── database.py

│   │   ├── http_handler.py

│   │   ├── http_interceptor.py

│   │   └── __init__.py

│   ├── extends

│   │   ├── banner.py

│   │   ├── functions.py

│   │   └── __init__.py

│   ├── __init__.py

│   ├── models

│   │   ├── base.py

│   │   ├── clazz.py

│   │   ├── __init__.py

│   │   ├── school.py

│   │   └── user.py

│   ├── plugins

│   │   ├── flask_celery.py

│   │   └── __init__.py

│   ├── services

│   │   ├── base.py

│   │   ├── __init__.py

│   │   └── statement.py

│   └── views

│   ├── async_handler.py

│   ├── error_handler.py

│   ├── index_hander.py

│   ├── __init__.py

│   ├── rest_clazz_handler.py

│   ├── rest_login_handler.py

│   ├── rest_school_handler.py

│   └── rest_user_handler.py

├── git-user-config.sh

├── README.md

├── requirements.txt

├── static

│   ├── css

│   │   └── layout.css

│   ├── favicon.ico

│   ├── images

│   │   └── 0.jpg

│   └── js

│   └── app.js

├── stop-app.sh

├── templates

│   ├── 404.html

│   ├── examples

│   │   ├── extensions_flask_form.html

│   │   └── extensions_flask_sqlAlchemy.html

│   ├── index.html

│   └── layout.html

└── test

├── config.properties

├── __init__.py

├── plugins

│   ├── __init__.py

│   └── test_celery_task.py

├── test_banner.py

├── test_celery.py

├── test_db.py

├── test_extend_func.py

├── test_lru.py

├── test_platform.py

└── views

└── test_school.py

数据库封装

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Time : 2018/6/5 20:52

# @Author : TOM.LEE

# @File : database.py

# @Software: PyCharm

from flaskapp import db

from ..common import ConsoleLogger, relative_path, MySQLDataError

__all__ = ['Persistence', 'Modify', 'Modify2', 'Remove', 'Query', 'Query2']

logger = ConsoleLogger(name=relative_path(__file__))

class Database(object):

"""

database interface

"""

class Transactional(Database):

def __init__(self, **kwargs):

"""

事务层

:param auto_commit: 是否自动提交

"""

self._auto_commit = kwargs.get('auto_commit', True)

self.model = kwargs.get('model_class')

if not self.model:

raise AssertionError(': Required parameter model_class is not present.'

.format(self.__class__.__name__))

self.session = db.session

# logger.info('init Transactional')

def auto_commit(self):

"""

是否自动提交事务

:return:

"""

if self._auto_commit:

self.session.commit()

def _check_type(self, obj):

if not isinstance(obj, self.model):

raise AssertionError('obj must be type.'

.format(self.model.__class__.__name__))

class Persistence(Transactional):

def __init__(self, **kwargs):

super(Persistence, self).__init__(**kwargs)

# logger.info('init Persistence')

def _load(self, obj):

self._check_type(obj)

self.session.add(obj)

def save(self, obj):

# 理论上该方法可以被任意对象使用

self._load(obj)

self.auto_commit()

return obj

def batch_save(self, arr):

[self._load(obj) for obj in arr]

self.auto_commit()

return arr

class Modify(Transactional):

def __init__(self, **kwargs):

super(Modify, self).__init__(**kwargs)

# logger.info('init Modify')

def _flush(self, primary_key, obj_dict):

if not isinstance(obj_dict, dict):

raise AssertionError('obj_dict must be dict type.')

obj = self.model.query.get(primary_key)

if not obj:

raise MySQLDataError(message='row not found for primary_key {}.'

.format(primary_key))

for filed in obj_dict:

setattr(obj, filed, obj_dict[filed])

return obj

def update(self, primary_key, obj_dict):

obj = self._flush(primary_key, obj_dict)

self.auto_commit()

return obj

def batch_update(self, arr):

data = [self._flush(primary_key, obj_dict) for primary_key, obj_dict in arr]

self.auto_commit()

return data

class Remove(Transactional):

def __init__(self, **kwargs):

super(Remove, self).__init__(**kwargs)

# logger.info('init Remove')

def _del(self, primary_key):

obj = self.model.query.get(primary_key)

if not obj:

raise MySQLDataError(message='row not found for primary_key {}.'

.format(primary_key))

self.session.delete(obj)

return primary_key

def delete(self, primary_key):

data = self._del(primary_key)

self.auto_commit()

return data

def batch_delete(self, arr):

data = [self._del(primary_key) for primary_key in arr]

self.auto_commit()

return data

class Query(Database):

def __init__(self, **kwargs):

# logger.info('init Query')

self.model = kwargs.get('model_class', None)

if not self.model:

raise AssertionError(': model_class is not found.'

.format(self.__class__.__name__))

def _build_query(self, limit=-1, order_by=None, filters=None):

_query = self.model.query

if limit > 0:

_query = _query.limit(limit)

if order_by and getattr(self.model, order_by, None):

_query = _query.order_by(getattr(self.model, order_by))

filters = filters or []

for _filter in filters:

_query = _query.filter(_filter)

return _query

def _item(self, items):

if not items:

return items

call_json = getattr(self.model, 'json', None)

if isinstance(items, (list, tuple, set)):

return [call_json(i) for i in items] if call_json else items

return call_json(items) if call_json else items

def get(self, primary_key):

return self._item(self._build_query().get(primary_key))

def query_all(self, limit=-1, order_by=None):

return self._item(self._build_query(limit=limit, order_by=order_by).all())

def query_filter_all(self, **kwargs):

return self._item(self._build_query().filter_by(**kwargs).all())

def query_filter_first(self, **kwargs):

return self._item(self._build_query().filter_by(**kwargs).first())

def query_filters(self, filters=None):

if not filters:

return self.query_all()

assert isinstance(filters, (list, tuple, set))

return self._item(self._build_query(filters=filters).all())

def count(self, filters=None, **kwargs):

return self._build_query(filters=filters).filter_by(**kwargs).count()

class Modify2(Database):

@classmethod

def _auto_commit(cls):

db.session.commit()

@classmethod

def _flush(cls, model, primary_key, obj_dict):

if not isinstance(obj_dict, dict):

raise AssertionError('obj_dict must be dict type.')

obj = model.query.get(primary_key)

if not obj:

raise MySQLDataError(message='row not found for primary_key {}.'

.format(primary_key))

for filed in obj_dict:

setattr(obj, filed, obj_dict[filed])

return obj

def update(self, model, primary_key, obj_dict):

obj = self._flush(model, primary_key, obj_dict)

self._auto_commit()

return obj

def batch_update(self, model, arr):

data = [self._flush(model, primary_key, obj_dict) for primary_key, obj_dict in arr]

self._auto_commit()

return data

class Query2(Database):

def __init__(self):

"""需要传入实体类型来使用该类"""

# logger.info('init Query2')

def _build_query(self, model, limit=-1, order_by=None, filters=None):

_ = self

_query = model.query

if limit > 0:

_query = _query.limit(limit)

# 假如属性存在,则加入过滤条件

if order_by and getattr(model, order_by, None):

_query = _query.order_by(getattr(model, order_by))

filters = filters or []

for _filter in filters:

_query = _query.filter(_filter)

return _query

def _item(self, model, items):

_ = self

if not items:

return items

call_json = getattr(model, 'json', None)

if not call_json:

return items

if isinstance(items, (list, tuple, set)):

return [call_json(i) for i in items] if call_json else items

return call_json(items) if call_json else items

def get(self, model, primary_key):

return self._item(model, self._build_query(model).get(primary_key))

def query_all(self, model, limit=-1, order_by=None):

return self._item(model, self._build_query(model, limit=limit, order_by=order_by).all())

def query_filter_all(self, model, **kwargs):

"""query_filter_all(username='admin')"""

return self._item(model, self._build_query(model).filter_by(**kwargs).all())

def query_filter_first(self, model, **kwargs):

return self._item(model, self._build_query(model).filter_by(**kwargs).first())

def query_filters(self, model, filters=None):

if not filters:

return self.query_all(model)

assert isinstance(filters, (list, tuple, set))

return self._item(model, self._build_query(model, filters=filters).all())

banner 配置

AAffA0nNPuCLAAAAAElFTkSuQmCC

接口浏览

AAffA0nNPuCLAAAAAElFTkSuQmCC

错误处理

页面请求:

AAffA0nNPuCLAAAAAElFTkSuQmCC

curl请求:

AAffA0nNPuCLAAAAAElFTkSuQmCC

级联查询转json

AAffA0nNPuCLAAAAAElFTkSuQmCC

拓展flask启动方法start

from flaskapp import app

if __name__ == "__main__":

app.start()

# app.start(port=5258, debug=False)

数据库更新迁移

$ python manager.py db init

$ python manager.py db migrate

Dockerfile 构建

$ ./docker-build.sh

celery异步处理

见项目test目录test_celery.py

swagger配置

见项目examples目录swagger_for_api.py

更多信息见项目源码,希望对你有所帮助

Authors

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值