【Python】【Flask】【一】demo

 

 

 

 

 

 

cankao: http://www.pythondoc.com/flask/tutorial/index.html

【database_operator.py】


import os, re
from importlib.machinery import SourceFileLoader
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
from .exceptions import DataBaseOperationException
from .utility import Utility

os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.AL32UTF8'

def error_handle(func):
def wrapper(database_operator, *args, **kwargs):
try:
return func(database_operator, *args, **kwargs)
except SQLAlchemyError as e:
database_operator.session_provider.rollback()
raise e
finally:
database_operator.session_provider.close()
return wrapper


class DataOperatorSingleton(type):
def __init__(cls, name, bases, dict):
super(DataOperatorSingleton, cls).__init__(name, bases, dict)
cls.__instance = None

def __call__(cls, *args, **kwargs):
_key = str(args) + str(kwargs)
if cls.__instance is None:
cls.__instance = {
_key: super(DataOperatorSingleton, cls).__call__(*args, **kwargs)
}

elif _key not in cls.__instance:
cls.__instance.update({
_key: super(DataOperatorSingleton, cls).__call__(*args, **kwargs)
})

return cls.__instance.get(_key)

class DataBaseOperator(object, metaclass=DataOperatorSingleton):
def __init__(self, model_path_str, env='qa', split_tb_hook=None, split_db_hook=None):
self.__env = env
self.__table_cls = None
self.session_provider = None
self.__db_hook = None
self.__tb_hook = None
self.__is_select = False
self.utl = Utility()

db_model = re.search(r'(\w+)\.py$', model_path_str).group(1)
try:
load_path = self.utl.intersection_of_path(model_path_str)
self.__module = SourceFileLoader(db_model, load_path).load_module()
except ModuleNotFoundError:
raise ModuleNotFoundError('The "{0}" mapping classes has not yet been generated!').format(db_model)

self.__connect_info = self.__module.CONNECT_INFO
self.__database_type = self.__module.CONNECT_INFO['connect_tag']
if not self.__db_hook:
self._build_session_provider()

def __get_table_cls(self, filter_d):
for cls_name in self.__module.__dict__.keys():
if re.match(r'^(t_)?{0}(_view)?$'.format(self.__org_table_name), self.utl.camel_to_underline(cls_name)):
self.__table_cls = getattr(self.__module, cls_name)
break
else:
continue

if self.__table_cls is None:
raise DataBaseOperationException('The {} table class is not definition!'.format(self.__org_table_name))

def _build_session_provider(self):
if self.__database_type == 'mysql':
connect_string = 'mysql+pymysql://{usr}:{pwd}@{url}/{db}?charset=utf8'.format(**self.__connect_info[self.__env])
#connect_string = 'mysql+mysqldb://{usr}:{pwd}@{url}/{db}?charset=utf8'.format(**self.__connect_info[self.__env])
#parameters = {"echo": False}
#engine = create_engine(connect_string, **parameters)
#engine = create_engine(connect_string, unix_socket='/tmp/mysql.sock', echo=False)
engine = create_engine(connect_string, max_overflow=5, echo=False, pool_pre_ping=True)
session = sessionmaker(bind=engine)
self.session_provider = session()

@error_handle
def __get_table_row(self, order_by_column_name=None, result_mode='all', limit=10, **filters):
self.__is_select = True
self.__get_table_cls(filters)

self.session_provider.commit() #强制刷新缓存
sql_query = self.session_provider.query(self.__table_cls).filter_by(**filters)
if order_by_column_name:
order_by_mode, order_by_column = order_by_column_name.split('_', 1)
order_by_func = getattr(sqlalchemy, order_by_mode)
sql_query = sql_query.order_by(order_by_func(order_by_column))
return getattr(sql_query.limit(limit), result_mode)() if result_mode == 'all' else getattr(sql_query, result_mode)()

@error_handle
def __update_table_row(self, update_dict, **filters):
if not isinstance(update_dict, dict):
raise Exception('Update statement %s is wrong. ' % update_dict)

self.__is_select = False
self.__get_table_cls(filters)

self.session_provider.query(self.__table_cls).filter_by(**filters).update(update_dict)
self.session_provider.commit()

@error_handle
def __delete_table_row(self, **filters):
self.__is_select = False
self.__get_table_cls(filters)

if isinstance(self.__table_cls, sqlalchemy.Table):
sql_s = ''
_keys = list(filters.keys())

for i in range(len(_keys)):
if _keys[i] == _keys[-1]:
sql_s += '{}={}'.format(_keys[i], filters[_keys[i]])
else:
sql_s += '{}={} and '.format(_keys[i], filters[_keys[i]])

del_st = self.__table_cls.delete().where(sql_s)
self.session_provider.execute(del_st)
self.session_provider.commit()

else:
rows = self.session_provider.query(self.__table_cls).filter_by(**filters).all()
if rows is None:
raise SQLAlchemyError('Cannot be found in %s table conditions for %s' % (self.__table_cls.__tablename__, filters))
else:
for row in rows:
self.session_provider.delete(row)
self.session_provider.commit()


@error_handle
def __add_table_row(self, **insert_dict):
self.__is_select = False
self.__get_table_cls(insert_dict)

if not isinstance(insert_dict, dict):
raise Exception('Add statement %s is wrong.' % insert_dict)

if isinstance(self.__table_cls, sqlalchemy.Table):
ins = self.__table_cls.insert().values(**insert_dict)
self.session_provider.execute(ins)
else:
self.session_provider.add(self.__table_cls(**insert_dict))
self.session_provider.commit()

def __getattr__(self, item):
ghost_func = re.search(r'(^get_|^update_|^add_|^delete_)(\w+$)', item)
if ghost_func:
self.__org_table_name = ghost_func.group(2)

if 'get' in item:
return self.__get_table_row
elif 'update' in item:
return self.__update_table_row
elif 'add' in item:
return self.__add_table_row
elif 'delete' in item:
return self.__delete_table_row

else:
raise AttributeError(" '%s' object has no attribute '%s'" % (self.__class__.__name__, item))

【exceptions.py】


class DataPatternWarning(Warning):
pass

class VerifyWarning(Warning):
pass


class DataBaseOperationException(Exception):
pass

【utility.py】


import time, collections, inspect, os, imaplib, sys, hashlib, re
from faker import Factory
from functools import wraps

class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls.__instance = None

def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls.__instance

class Utility(object, metaclass=Singleton):
def __init__(self):
self.fake_cn = Factory.create('zh_CN')
self.fake_en = Factory.create()

@staticmethod
def camel_to_underline(camel_format):
'''
驼峰格式转下划线格式
:param camel_format:
:return:
'''
underline_format = ''
if isinstance(camel_format, str):
for i in range(len(camel_format)):
underline_format += (camel_format[i].isupper() and i !=0) and '_' + camel_format[i].lower() or camel_format[i].lower()
return underline_format

@staticmethod
def intersection_of_path(file_path):
'''
拼接绝对路径的文件路径,方便文件的读取
:param file_path:
:return:
'''
relative_list = os.path.normpath(file_path).split(os.sep)
sys_path_now_list = os.path.dirname(__file__).split(os.sep)[1:]
for i in range(1, len(sys_path_now_list)):
list_path = ''.join(['/%s' % y for y in sys_path_now_list[:-i]])
sys_path_dirs = os.listdir(list_path)
if relative_list[0] in sys_path_dirs:
return os.path.join(list_path, file_path)




if __name__ == '__main__':
print ( '\n\.')




[account.py]
from sqlalchemy import String, Column, DECIMAL, Date, DateTime, TIMESTAMP, Table, Text, text
from sqlalchemy.dialects.mysql import BIGINT, INTEGER, SMALLINT, VARCHAR, DATETIME
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
metedata = Base.metadata

CONNECT_INFO = {'connect_tag': 'mysql',
'qa': {'usr': 'root', 'pwd': '123', 'url': 'localhost:3306', 'db': 'account'}}


class FlaskerTbOne(Base):
__tablename__ = 'flasker_tb_one'

id = Column(INTEGER(4), primary_key=True)
title = Column(String(255), nullable=False)
text = Column(String(255), nullable=False)


[style.css]
body               { font-family: sans-serif;  backgroud: #eee; }
a, h1, h2 { color: #377BA8; }
h1, h2 { font-family: 'Georgia', serif; margin:0; }
h1 { border-bottom: 2px solid #eee; }
h2 { font-size: 1.2em; }
.page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
padding: 0.8em; background: white; }
.entries { list-style: none; margin: 0; padding: 0; }
.entries li { margin: 0.8em 1.2em; }
.entries li h2 { margin-left: -1em; }
.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl { font-weight: bold; }
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
margin-bottom: 1em; background: #fafafa; }
.flash { background: #CEE5F5; padding: 0.5em;
border: 1px solid #AACBE2; }
.error { background: #F0D6D6; padding: 0.5em; }



【layout.html】
<!DOCTYPE html>


<title>Flaskr</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">



<div class="page">
<h1>Flaskr</h1>
<div class="metanav">
{% if not session.logged_in %}
<a href="{{ url_for('login') }}">log in </a>
{% else %}
<a href="{{ url_for('logout') }}">log out</a>
{% endif %}

</div>
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}

</div>



[login.html]
{% extends 'layout.html' %}
{% block body %}
<h2>Login</h2>
{% if error %}<p class="error"><strong>Error:</strong>{{ error }}{% endif %}
<form action="{{ url_for('login') }}" method="post">
<dl>
<dt>Username:
<dd><input type="text" name="username">
<dt>Password:
<dd><input type="password" name="password">
<dd><input type="submit" value="Login">
</dl>

</form>
{% endblock %}


[show_entities.html]
{% extends 'layout.html' %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method="post" class="add-entry">
<dl>
<dt>Title:
<dd><input type="text" size="30" name="title">
<dt>Text:
<dd><textarea name="text" rows="5" cols="40"></textarea>
<dd><input type="submit" value="Share">
</dl>

</form>
{% endif %}
<ul class="entries">
{% for entry in entries %}
<li><h2>{{ entry.title }}}</h2>{{ entry.text|safe }}
{% else %}
<li><em>Unbelievable. No entries here so far </em>
{% endfor %}

</ul>
{% endblock %}



[conftest.py]



import pytest
from flasker.kernel.database_operator import DataBaseOperator

DB_MODELS_PATH = 'untitled3/flasker/models/{}.py'



def pytest_addoption(parser):
parser.addoption('--test_env', action='store', default='qa', dest='test_env', help='my option: qa or dev')

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()

setattr(item, 'rep_' + rep.when, rep)

@pytest.fixture(scope='session')
def environment(request):
return request.config.getoption('test_env')

@pytest.fixture(scope='session')
def account_data(environment):
return DataBaseOperator(DB_MODELS_PATH.format('account'), environment)



[flasker_one_test.py]
import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
import pytest



class TestFlasker(object):

@pytest.mark.basic_wxue_case
def test_one(self, account_data):
account_d = account_data.get_flasker_tb_one(result_mode='one', id=1)
print ('**************account.text=***************' + account_d.text)
assert 0




[flaskr.py]
import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
import pytest
from flasker.kernel.database_operator import DataBaseOperator
from flasker.models.account import FlaskerTbOne

DB_MODELS_PATH = 'flask_learn/flasker/models/{}.py'
app = Flask(__name__)

def get_db():
db = getattr(g, '_database', None)
if db is None:
db = DataBaseOperator(DB_MODELS_PATH.format('account'))
g._database = db
return db

@app.before_request
def before_request():
get_db()


@app.route('/')
def show_entries():
account_d = g._database.get_flasker_tb_one(result_mode='all')
entries = [dict(title = row.title, text = row.text) for row in account_d]
return render_template('show_entries.html', entries=entries)


@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g._database.add_flasker_tb_one(title=request.form['title'], text = request.form['text'])
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))

@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)

@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

if __name__ == '__main__':

app.debug = True
app.config.from_object('settings.FlaskSetting')
app.run()




[settings.py]


class FlaskSetting:
USERNAME = 'admin'
PASSWORD = '123'






demo_two
【flaskr_test】 unittest + flask



from flasker import flaskr
import unittest
import os
import tempfile


class FlaskrTestCase(unittest.TestCase):

def setUp(self):
self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
    flaskr.app.config.from_object('settings.FlaskSetting')
    flaskr.app.config['TESTING'] = True
self.app = flaskr.app.test_client()
with flaskr.app.app_context():
flaskr.get_db()

def tearDown(self):
os.close(self.db_fd)
os.unlink(flaskr.app.config['DATABASE'])

def test_empty_db(self):
rv = self.app.get('/')
assert 'text -> snow is coming' in str(rv.data)

def login(self, username, password):
# 因为登陆登出页面都会重定向, 我们将客户端设置为follow_redirects
return self.app_client.post('login', data=dict(username=username, password=password), follow_redirects= True)

def logout(self):
return self.app_client.get('/logout', follow_redirects=True)

def test_b_login_logout(self):
rv = self.login('admin', '123')
assert 'You were logged in' in str(rv.data)
rv = self.logout()
assert 'You were logged out' in str(rv.data)
rv = self.login('adminx', 'default')
assert 'Invalid username' in str(rv.data)
rv = self.login('admin', '3333')
assert 'Invalid password' in str(rv.data)

def test_c_add(self):
self.login('admin', '123')
rv = self.app_client.post('/add', data=dict(title='<Hello>', text='<strong>HTML</strong> allowed here'), follow_redirects=True)
assert 'No entries here so far' not in str(rv.data)
assert '&lt;Hello&gt;' in str(rv.data)
assert '<strong>HTML</strong> allowed here' in str(rv.data)


if __name__ == '__main__':
unittest.main()


'''
其他文件参考本页面demo1
'''




demo three
【flaskr_two】 用到的其他文件同demo one
"""
# egg... 伪造资源和上下文

from flask import Flask, g

app = Flask(__name__)
from contextlib import contextmanager
from flask import appcontext_pushed

@contextmanager
def user_set(app, user):
def handler(sender, **kwargs):
g.user = user
with appcontext_pushed.connected_to(handler, app):
yield

from flask import json, jsonify

@app.route('/users/me')
def users_me():
return jsonify(username=g.user['text'])

my_user = {'text': 'textOne'}
with user_set(app, my_user):
with app.test_client() as c:
resp = c.get('/users/me')
data = json.loads(resp.data)
assert data['username'] == my_user['text']


'''
遇到错误:RuntimeError: signalling support is unavailable because the blinker library is not installed.
参考解决方法地址: https://stackoverflow.com/questions/20381160/importing-a-flask-security-instance-into-my-views-module-breaks-my-webapp
简而言之就是 错误出现在with appcontext_pushed.connected_to(handler, app):,除了需要引入第三方库flask,还需要pip blinker
'''

# egg.. 保存上下文 app.test_client() 和with 联合使用

from flask import Flask, request
app = Flask(__name__)


with app.test_client() as c:
rv = c.get('/?tequila=42')
assert request.args['tequila'] == '42'


'''
运行成功
'''



# egg.. 保存上下文 app.test_client() 和with 不联合使用
from flask import Flask, request
app = Flask(__name__)

c = app.test_client()
rv = c.get('/?wxue=88')
assert request.args['wxue'] == '88'
'''
Traceback (most recent call last):
File "/Users/ruique/PycharmProjects/flask_test_one/flasker/flaskr_two.py", line 60, in <module>
assert request.args['wxue'] == '88'
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/globals.py", line 37, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.

'''



# egg.. 访问和修改sessions flask.session

from flask import Flask,session
app = Flask(__name__)

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT7878' #必须设置,否则报错RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.

with app.test_client() as c:
rv = c.get('/')
session['foo'] = 42
assert session['foo'] == 42

'''
运行通过
网站上说:
这并不能使它可能还可以修改会话或访问会话在发送请求之前。
所以也不知道此处为什么运行通过额
'''


# egg.. 访问和修改sessions with app.test_client().session_transaction()
'''
从 Flask 0.8 开始, 我们提供一个叫做 ” Session 事务“ 的东西用于模拟适当的调用,从而在测试客户端的上下文中打开一个 Session, 并用于修改。在事务的结尾,Session 将被恢复为原来的样子。这些都独立于 Session 的后端使用
'''
from flask import Flask,session
app = Flask(__name__)

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT7878' #必须设置,否则报错RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.


with app.test_client() as c:
with c.session_transaction() as sess:
sess['a_key'] = 'a value'
assert session['a_key'] == 'a value'

'''
Traceback (most recent call last):
File "/Users/ruique/PycharmProjects/flask_test_one/flasker/flaskr_two.py", line 111, in <module>
assert session['a_key'] == 'a value'
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/werkzeug/local.py", line 378, in <lambda>
__getitem__ = lambda x, i: x._get_current_object()[i]
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/globals.py", line 37, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

'''




# egg.. 访问和修改sessions with app.test_client().session_transaction()
'''
从 Flask 0.8 开始, 我们提供一个叫做 ” Session 事务“ 的东西用于模拟适当的调用,从而在测试客户端的上下文中打开一个 Session, 并用于修改。在事务的结尾,Session 将被恢复为原来的样子。这些都独立于 Session 的后端使用
'''
from flask import Flask,session
app = Flask(__name__)

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT7878' #必须设置,否则报错RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.


with app.test_client() as c:
with c.session_transaction() as sess:
sess['a_key'] = 'a value'
assert sess['a_key'] == 'a value'

'''
OK

'''


# egg ... 配置

from flask import Flask
app = Flask(__name__)

app.config['DEBUG'] = True

print (app.debug)

app.config.update(
DEBUG=False
)

print (app.debug)


'''
True
False

'''


'''
内置的配置值
下列配置值是 Flask 内部使用的:

DEBUG 启用/禁用调试模式
TESTING 启用/禁用测试模式
PROPAGATE_EXCEPTIONS 显式地允许或禁用异常的传播。如果没有设置或显式地设置为 None ,当 TESTING 或 DEBUG 为真时,这个值隐式地为 true.
PRESERVE_CONTEXT_ON_EXCEPTION 默认情况下,如果应用工作在调试模式,请求上下文不会在异常时出栈来允许调试器内省。 这可以通过这个键来禁用。你同样可以用这个设定来强制启用它,即使没有调试执行,这对调试生产应用很有用(但风险也很大)
SECRET_KEY 密钥
SESSION_COOKIE_NAME 会话 cookie 的名称。
SESSION_COOKIE_DOMAIN 会话 cookie 的域。如果不设置这个值,则 cookie 对 SERVER_NAME 的全部子域名有效
SESSION_COOKIE_PATH 会话 cookie 的路径。如果不设置这个值,且没有给 '/' 设置过,则 cookie 对 APPLICATION_ROOT 下的所有路径有效。
SESSION_COOKIE_HTTPONLY 控制 cookie 是否应被设置 httponly 的标志, 默认为 True
SESSION_COOKIE_SECURE 控制 cookie 是否应被设置安全标志,默认为 False
PERMANENT_SESSION_LIFETIME 以 datetime.timedelta 对象控制长期会话的生存时间。从 Flask 0.8 开始,也可以用整数来表示秒。
SESSION_REFRESH_EACH_REQUEST 这个标志控制永久会话如何刷新。如果被设置为 True (这是默认值),每一个请求 cookie 都会被刷新。如果设置为 False ,只有当 cookie 被修改后才会发送一个 set-cookie 的标头。非永久会话不会受到这个配置项的影响 。
USE_X_SENDFILE 启用/禁用 x-sendfile
LOGGER_NAME 日志记录器的名称
SERVER_NAME 服务器名和端口。需要这个选项来支持子域名 (例如: 'myapp.dev:5000' )。注意 localhost 不支持子域名,所以把这个选项设置为 “localhost” 没有意义。设置 SERVER_NAME 默认会允许在没有请求上下文而仅有应用上下文时生成 URL
APPLICATION_ROOT 如果应用不占用完整的域名或子域名,这个选项可以被设置为应用所在的路径。这个路径也会用于会话 cookie 的路径值。如果直接使用域名,则留作 None
MAX_CONTENT_LENGTH 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码
SEND_FILE_MAX_AGE_DEFAULT: 默认缓存控制的最大期限,以秒计,在 flask.Flask.send_static_file() (默认的静态文件处理器)中使用。对于单个文件分别在 Flask 或 Blueprint 上使用 get_send_file_max_age() 来覆盖这个值。默认为 43200(12小时)。
TRAP_HTTP_EXCEPTIONS 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样, 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。
TRAP_BAD_REQUEST_ERRORS Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。如果这个值被设置为 True ,你只会得到常规的回溯。
PREFERRED_URL_SCHEME 生成URL的时候如果没有可用的 URL 模式话将使用这个值。默认为 http
JSON_AS_ASCII 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False , Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。比如 jsonfiy 会自动地采用 utf-8 来编码它然后才进行传输。
JSON_SORT_KEYS 默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。
JSONIFY_PRETTYPRINT_REGULAR 如果这个配置项被 True (默认值), 如果不是 XMLHttpRequest 请求的话(由 X-Requested-With 标头控制) json 字符串的返回值会被漂亮地打印出来。


关于 SERVER_NAME 的更多
SERVER_NAME 用于子域名支持。因为 Flask 在得知现有服务器名之前不能猜测出子域名部分,所以如果你想使用子域名,这个选项是必要的,并且也用于会话 cookie 。

请注意,不只是 Flask 有不知道子域名是什么的问题,你的 web 浏览器也会这样。现代 web 浏览器不允许服务器名不含有点的跨子域名 cookie 。所以如果你的服务器名是 'localhost' ,你不能在 'localhost' 和它的每个子域名下设置 cookie 。请选择一个合适的服务器名,像 'myapplication.local' , 并添加你想要的服务器名 + 子域名到你的 host 配置或设置一个本地 绑定 。



'''

'''
# egg 配置
flask几种参数配置方法
博客分类: python

方法一、直接配置

Python代码 收藏代码
app.config['HOST']='xxx.a.com'
print app.config.get('HOST')
方法二、通过环境变量加载配置

export MyAppConfig=/path/to/settings.cfg

Python代码 收藏代码
app.config.from_envvar('MyAppConfig')

这样将会加载环境变量指向的配置文件,并加载

方法三、通过对象加载

Python代码 收藏代码
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'

class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'

class DevelopmentConfig(Config):
DEBUG = True

class TestingConfig(Config):
TESTING = True

from flask import Flask
app = Flask(__name__)

app.config.from_object(ProductionConfig)
print app.config.get('DATABASE_URI') # mysql://user@localhost/foo

或者:


Java代码 收藏代码
from flask import Flask
import default_config
app = Flask(__name__)

app.config.from_object(default_config) # 这里 defualt_config是一个对象
print app.config.get('HOST')


Python代码 收藏代码
# default_config.py
HOST = 'localhost'
PORT = 5000
DEBUG = True

方法四、通过配置文件
Python代码 收藏代码
app.config.from_pyfile('default_config.py') # 这里defualt_config.py是文件

# default_config.py
HOST = 'localhost'
PORT = 5000
DEBUG = True

Python代码 收藏代码
# 使用配置
print app.config['HOST']
--end









# egg 订阅信号

from flask import template_rendered
from contextlib import contextmanager
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
from flasker.kernel.database_operator import DataBaseOperator

DB_MODELS_PATH = 'flask_test_one/flasker/models/{}.py'

app = Flask(__name__)

def get_db():
db = getattr(g,'_database',None)
if db is None:
db = DataBaseOperator(DB_MODELS_PATH.format('account'))
g._database = db # 存入Flask.g对象中
return db

def init_db():
with app.app_context():
db = get_db()


@app.before_request
def before_request():
get_db()

@app.route('/')
def show_entries():
account_d = g._database.get_flasker_tb_one(result_mode='all')
entries = [dict(title=row.title, text=row.text) for row in account_d]
return render_template('show_entries.html', entries=entries)

@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g._database.add_flasker_tb_one(title=request.form['title'], text=request.form['text'])
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))

@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in ')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)

@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'


@contextmanager
def captured_templates(app):
recorded = []
def record(sender, template, context, **extra):
recorded.append((template, context))
template_rendered.connect(record, app)
try:
yield recorded
finally:
template_rendered.disconnect(record, app)


with captured_templates(app) as templates:
rv = app.test_client().get('/')
assert rv.status_code == 200
assert len(templates) == 1
template, context = templates[0]
assert template.name == 'show_entries.html'
assert len(context['entries']) == 1



if __name__ == '__main__':

app.debug = True
app.config.from_object('settings.FlaskSetting')
app.run()



'''
用到的文件同
https://www.cnblogs.com/suren2017/p/10875801.html
'''



# egg... 信号 2 connected_to()
'''
它允许你临时地把函数订阅到信号并使用信号自己的上下文管理器。因为这个上下文管理器的返回值不能由我们决定,所以必须把列表作为参数传入:
'''


from flask import template_rendered
from contextlib import contextmanager
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
from flasker.kernel.database_operator import DataBaseOperator

DB_MODELS_PATH = 'flask_test_one/flasker/models/{}.py'

app = Flask(__name__)

def get_db():
db = getattr(g,'_database',None)
if db is None:
db = DataBaseOperator(DB_MODELS_PATH.format('account'))
g._database = db # 存入Flask.g对象中
return db

def init_db():
with app.app_context():
db = get_db()


@app.before_request
def before_request():
get_db()

@app.route('/')
def show_entries():
account_d = g._database.get_flasker_tb_one(result_mode='all')
entries = [dict(title=row.title, text=row.text) for row in account_d]
return render_template('show_entries.html', entries=entries)

@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g._database.add_flasker_tb_one(title=request.form['title'], text=request.form['text'])
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))

@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in ')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)

@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))

app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'


def captured_templates(app, recorded, **extra):
def record(sender, template, context):
recorded.append((template, context))
return template_rendered.connected_to(record, app)


templates = [('template_one.html', {'entries': [{'title': 1, 'text': 2}]})]
extra = {}

with captured_templates(app, templates, **extra):
rv = app.test_client().get('/')
assert rv.status_code == 200
assert len(templates) == 2 # 除了自己定义的还有自带的tuple (<Template 'show_entries.html'>, entries的dict)
template, context = templates[0]
assert template == 'template_one.html'
assert len(context['entries']) == 1


"""





























 

posted @ 2019-05-16 15:14  素人渔芙2017  阅读(874)  评论(0编辑  收藏  举报