Flask基础学习最终篇-与Python结合-下

1. 使用多线程进行异步发送邮件

我们知道在Flask中存在线程隔离,如果我们直接开启多线程的话是无法满足我们的需求的。

我们再看下current_app和flask核心对象实例化后的区别app = Flask()

current_app是使用的代理,指代的并不是flask核心对象。在之前我们知道指代的是对应的堆栈的栈顶。但是当我们在一个请求中直接新开一个线程的时候,current_app就会出现指代为空的现象。

代理对象是收到线程id的影响的,因为本身就是在做线程隔离。

我们知道flask的核心对象是全局唯一的,如果我们要新开一个线程需要使用应用程序上下文,可以使用 current_app_get_current_object方法获得真正的核心对象而不是代理对象。

下面是在发送邮件的时候使用新的线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 异步发送的函数
def send_async_email(app, msg):
# 需要在应用上下文环境中使用
with app.app_context():
try:
mail.send(msg)
except Exception as e:
pass


def send_email(to, subject, template, **kwargs):
# 使用 _get_current_object 获得真正的flask核心对象
app = current_app._get_current_object()
msg = Message(subject, sender=app.config['MAIL_SENDER'], recipients=[to])
# 邮件可以发生html
msg.html = render_template(template + '.html', **kwargs)
thr = Thread(target=send_async_email, args=[app, msg])
thr.start()
return thr

具有记录性的字段尽量不要做模型关联

2. 使用枚举Enum来指代一些数字

有时我们数据库的某写字段存储的是整型,标识一些状态值等。这些字段的值一般都是设置为数字,但是每个数字的含义如果不解释清楚,则很容易看不懂具体逻辑。

我们可以使用枚举来存储一些数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class PendingStatus(Enum):
"""交易状态"""
waiting = 1
success = 2
reject = 3
redraw = 4

# 这里模拟switch
@classmethod
def pending_str(cls, status, key):
key_map = {
cls.waiting: {
'requester': '等待对方邮寄',
'gifter': '等待你邮寄'
},
cls.reject: {
'requester': '对方已拒绝',
'gifter': '你已拒绝'
},
cls.redraw: {
'requester': '你已撤销',
'gifter': '对方已撤销'
},
cls.success: {
'requester': '对方已邮寄',
'gifter': '你已邮寄,交易完成'
}
}
return key_map[status][key]


# 如何获取枚举的值 相比于其他的类变量,枚举的变量获得值需要在后面在上 .value
PendingStatus.waiting.value

# 如果我们每次都是加上 .value 这样代码很多冗余
# 我们这时可以对字段属性设置一下
_pending = Column('pending', SmallInteger, default=1)
@property
def pending(self):
return PendingStatus(self._pending)

@pending.setter
def pending(self, status):
self._pending = status.value

# 完成上面的配置 我们每次读取出来的就是一个枚举值 每次赋值的时候还是整型
# 在属性赋值或者查询的时候我们直接使用枚举类赋值就好了
drift = Drift.query.filter_by(gift_id=gid, pending=PendingStatus.waiting).first()

个人觉得这种方式很不好,还不如直接在模型中增加类变量,然后增加一个元组。下面看下我平时使用的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Load(db.Model):
__tablename__ = 'load'

LIANLIAN_WAY = 1 # 连连
MANUAL_WAY = 2 # 手动
MIFU_WAY = 3 # 米付
HUIJU_WAY= 4 #汇聚
REQWAY_TUPLE = (
(LIANLIAN_WAY, '连连'),
(MANUAL_WAY, '手动'),
(MIFU_WAY, '米付'),
(HUIJU_WAY, '汇聚')
)
REQWAY_DICT = dict(REQWAY_TUPLE)

这样配置,使用起来更简单。

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!