flask_mail 消息实例不是 JSON 可序列化的

Posted

技术标签:

【中文标题】flask_mail 消息实例不是 JSON 可序列化的【英文标题】:flask_mail Message instance is not JSON serializable 【发布时间】:2017-02-14 22:11:58 【问题描述】:

我正在尝试运行这个非常简单的烧瓶/芹菜应用程序:

  @celery.task
    def send_async_email(msg):
        with app.app_context():
            mail.send(msg)

    @celery.task(bind=True)

    @app.route('/', methods=['GET', 'POST'])

    def index():
        if request.method == 'GET':
            return render_template('index.html', email=session.get('email', ''))
        email = request.form['email']
        session['email'] = email

        msg = Message('Hello from Flask',
                      recipients=[request.form['email']])
        msg.body = 'This is a test email sent from a background Celery task.'
        print type(msg)
        print dir(msg)
        print 'msg.send'
        print msg.send
        print 'msg'
        print msg

        if request.form['submit'] == 'Send':

            send_async_email.delay(msg)
            flash('Sending email to 0'.format(email))
        else:

        return redirect(url_for('index'))

但它不起作用,因为这个 Message 类的实例不是 json 可序列化的,似乎不是这样:

    msg.send
    <bound method Message.send of <flask_mail.Message object at 0x7ffa94cd0290>>
    msg
    Content-Type: text/plain; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Subject: Hello from Flask
    From: flask@example.com

    EncodeError: <flask_mail.Message object at 0x7ffa94cd0290> is not JSON serializable

【问题讨论】:

相关github.com/inveniosoftware/invenio-accounts/pull/84/commits/… 【参考方案1】:

Celery 要求通过代理传递的对象可以直接序列化。 flask_mail.Message 对象不是。您应该更改 send_async_email(msg) 的方法签名以接受简单的 JSON 兼容对象。也就是说,原始字符串、整数、这些的字典或类似的东西。然后,您应该在该方法中移动 Message 的所有逻辑(从实例化到发送)。

例如:

@celery.task
def send_async_email(message_details):
    with app.app_context():
        msg = Message(message_details['subject'],
                      message_details['recipients'])
        msg.body = message_details['body']
        print type(msg)
        print dir(msg)
        print 'msg.send'
        print msg.send
        print 'msg'
        print msg
        mail.send(msg)

【讨论】:

【参考方案2】:

我发现通过简单地设置序列化并添加更改默认值就像一个魅力。

app.config.update(
accept_content=['json','pickle']
)

那么,

@celery.task(serializer='pickle')
def send_async_email(msg):

【讨论】:

【参考方案3】:

您能否尝试将您的烧瓶邮件版本降级到 0.9.0。

你可以用这个命令来做:

pip uninstall Flask-Mail
pip install Flask-Mail==0.9.0

【讨论】:

以上是关于flask_mail 消息实例不是 JSON 可序列化的的主要内容,如果未能解决你的问题,请参考以下文章

_external=True 在 flask_mail 中是啥意思?

flask_mail 似乎是在 pythonanywhere 中导入的,但是运行时 get error code: no module named

AFNetworking 返回一个 _NSCFData 对象而不是 JSON

为啥 FutureBuilder snapshot.data 返回“Post 实例”而不是 json?

Pharo Smalltalk - 消息转发,是不是可以截获消息并将其重定向到另一个对象(实例)?

由于错误的模式类型(JSON 而不是 AVRO),Pulsar 函数无法反序列化消息