- 在Jinja2模板中遍历多重字典时,不能使用索引来取值。
代码段:
运行项目时会报错:
jinja2.exceptions.UndefinedError: 'flask.config.Config object' has no attribute 'BLUELOG THEMES'
config是Flask内置的模板上下文变量,控制台打印下config,如下:
搞不懂为什么会出现上面这种错误,后面偶然发现把取值的写法换一下,就可以了。。。
{% for theme_name, display_name in config.BLUELOG_THEMES.items() %}
【To be continue...】
- 使用flask_wtf渲染表单,下拉列表字段是使用WTForms提供的SelectField类来表示HTML中的
标签,下拉列表的选项(即
标签)通过参数
choices
指定。choices
必须是一个包含两元素元组的列表,列表中的元组分别包含选项值和选项标签,我遇到了一个很奇怪的问题,表单部分代码如下:
class AutoTestFrom(FlaskForm):
framework = SelectField(label='测试框架', validators=[DataRequired()], coerce=int, default=1)
case_tag = SelectField(label='用例标签', validators=[DataRequired()], coerce=int, default=0,
render_kw={"placeholder": "请选择要运行的用例标签"})
...
...
submit = SubmitField(label='提交')
def __init__(self, *args, **kwargs):
super(AutoTestFrom, self).__init__(*args, **kwargs)
self.framework.choices = [(code, name) for code, name in [(1, 'Robot Framework'), (2, 'Jmeter')]]
self.case_tag.choices = [(code, name) for code, name in [(0, '全部用例'), (1, 'P1优先级'), (2, 'P2优先级'), (3, '无感停车')]]
...
...
在上面的代码中,framework 字段设置默认值为1, case_tag 字段设置默认值为0,两个字段都设置了DataRequired,但是实际在前端,case_tag 的默认值并没有生效,点击保存时会有以下提示信息:
如果把case_tag 的默认值设置为1,就可以正常保存成功,所以,我把case_tag的枚举值关系改为了从1开始,而不是从0开始。也就是说,在设置DataRequired验证器时,表单的默认选项值不能设置为0,否则就会出现以上我遇到的问题。
- 之前为了方便,在本地使用的数据库是SQLite,后续想改为MariaDB,与前者不同,Flask-SQLAlchemy并不会为MariaDB(MySQL)主动去建立一个Database。所以需要自己手动在mySQL中建立一个相应的数据库,然后才能使用Flask-SQLAlchemy对相应数据进行查找,验证等操作。如果没有事先创建,是不能使用mySQL的。
'''
测试连接 MariaDB
Date : 2019-05-13
'''
import pymysql
db = pymysql.connect(host='localhost', user='root', password='*******', database='*****')
cursor = db.cursor()
cursor.execute('SELECT VERSION()')
data = cursor.fetchone()
print(data)
cursor.execute("DROP TABLE IF EXISTS test")
sql = """CREATE TABLE test (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
- 从MongoDB中查询数据时,可能会遇到查询结果为空的问题,初始代码如下:
def check_result(self):
client, park_db = self._connect_to_mongo()
collection = park_db['ParkMallAllowance']
test = collection.find(self.filter)
# if test is None
if test.count_documents() == 0: # 检查MongoDB的返回结果是否为空
pass
else:
pass
client.close()
return test
刚开始是使用 if test is None
的条件来判断返回结果是否为空,但是发现结果为空的时候,find()方法返回的是一个Cursor 对象,如下:
然后又使用test.count_documents() == 0
来判断,代码会返回错误:
AttributeError: 'Cursor' object has no attribute 'count_documents'
最后在查询源码时,发现find_one()方法在查询结果为空时会返回None,所以最终使用如下方法解决问题:
def check_result(self):
client, park_db = self._connect_to_mongo()
collection = park_db['ParkMallAllowance']
test = collection.find_one(self.filter)
if test is None:
pass
else:
pass
client.close()
return test
pymongo 版本迭代比较快,网上找到的答案结果都已经过时了。
- 在创建数据库模型时,只要涉及到和用户进行数据交互的表,基本都需要有add_time和update_time字段,如下:
class Link(db.Model):
'''
侧边栏链接
'''
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
url = db.Column(db.String(255))
add_time = db.Column(db.DateTime, default=datetime.now)
# add_time = db.Column(db.DateTime, default=datetime.nowd())
update_time = db.Column(db.DateTime, default=datetime.now,onupdate=datetime.now)
在为时间字段设置默认值时,使用datetime.now
和datetime.now()
的区别如下:
- datetime.now 数据实际插入时间,每条数据插入时可自动根据当前时间生成;
- datetime.now() 固定的时间,即程序部署的时间,所有的数据都是这个固定时间;
所以,一般情况下,使用default=datetime.now
的方式比较符合正常需求。
为了记录每次数据的修改时间,需要为update_time
设置 onupdate=datetime.now
,这样只要字段值有变化,就会自动update更新时间,非常方便。
补充: flask_sqlalchemy中的default和server_default
- 开发 flask restful api 时,使用工具测试 POST 请求时,返回 结果一直是 400 BAD request,而GET请求是正常,后来猜想是因为自己开启了CSRF验证,于是在current_aoo.config中设置WTF_CSRF_CHECK_DEFAULT=False,果然可以正常返回结果了。
参考文章:https://blog.csdn.net/weixin_42218868/article/details/98896503