首页 > 技术文章 > TypeError: send_mail() argument after ** must be a mapping, not str

aidenzdly 2020-04-09 14:35 原文

在flask中,使用Celery实现一步发送邮件,在编写send_mail方法时,传入的参数写法要注意:

 

@celery.task
def send_mail(r, subject, template, **kwargs):
    app = current_app._get_current_object()
    msg = Message(
        subject=subject,
        recipients=[r],
        sender=app.config['MAIL_USERNAME']
    )
    msg.html = render_template(template + '.html', **kwargs)
    msg.body = render_template(template + '.txt', **kwargs)
    mail.send(msg)

以上是我的send_mail方法,一共有4个参数,前面三个是固定的,后面一个是**kwargs(里面传入键值)

 

当我在视图函数中传参数时,要注意书写格式:

send_mail.apply_async(args=[form.email.data, '账户激活', 'email/activate'],
                              kwargs={'username':form.username.data,'token':token.decode('utf-8')})

鼠标邮件+ctrl看apply_async方法:

 

 所以由上可知,当后面需要携带其他的键值对的时候(方便在前端渲染或者验证,比如username,token等),一定要把kwargs带着,不然会报错:

 

 

其次,携带的token需要是str,原本生成的token是字节bytes,需要decode为utf-8,否则也会报错:

 

 

 

以上是我在flask上使用Celery发送邮件时,需要注意的问题。

其次,在flask上使用Celery发送邮件,还需要注意几个问题:

  1. celery上下文的问题;

       2. 需要设置SERVER_NAME,也是因为上下文的问题,否则报错;

  我在下一篇随笔中记录一下,希望帮助有需要的人,避免走弯路~

 

推荐阅读