将WTForms表单数据传递给Celery任务

时间:2018-02-01 13:45:03

标签: python flask celery

我想将验证过的数据从WTForms表单传递给Celery任务。当我尝试传递表单时,我得到kombu.exceptions.EncodeError: Object of type 'MyForm' is not JSON serializable。如何将数据从WTForms传递给Celery任务?我是否需要编写自定义序列化程序?

File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/galander/Desktop/Projekty/PDf generator/pdf-generator-master/pdf-generator/main.py", line 64, in submit
generate.delay(form, new_pdf)
File "/home/galander/.local/lib/python3.6/site-packages/celery/app/task.py", line 413, in delay
return self.apply_async(args, kwargs)
File "/home/galander/.local/lib/python3.6/site-packages/celery/app/task.py", line 536, in apply_async
**options
File "/home/galander/.local/lib/python3.6/site-packages/celery/app/base.py", line 737, in send_task
amqp.send_task_message(P, name, message, **options)
File "/home/galander/.local/lib/python3.6/site-packages/celery/app/amqp.py", line 554, in send_task_message
**properties
File "/home/galander/.local/lib/python3.6/site-packages/kombu/messaging.py", line 169, in publish
compression, headers)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/messaging.py", line 252, in _prepare
body) = dumps(body, serializer=serializer)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
payload = encoder(data)
File "/usr/local/lib/python3.6/contextlib.py", line 99, in __exit__
self.gen.throw(type, value, traceback)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/serialization.py", line 54, in _reraise_errors
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
File "/home/galander/.local/lib/python3.6/site-packages/vine/five.py", line 178, in reraise
raise value.with_traceback(tb)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/serialization.py", line 50, in _reraise_errors
yield
File "/home/galander/.local/lib/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
payload = encoder(data)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/utils/json.py", line 72, in dumps
**dict(default_kwargs, **kwargs))
File "/usr/local/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/local/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/galander/.local/lib/python3.6/site-packages/kombu/utils/json.py", line 62, in default
return super(JSONEncoder, self).default(o)
File "/usr/local/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
kombu.exceptions.EncodeError: Object of type 'MyForm' is not JSON serializable
class MyForm(FlaskForm):
    name_of_the_file = StringField()
    first_name = StringField()
    number = DecimalField()
    date = DateField()

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    form = MyForm()

    if form.validate_on_submit():
        generate.delay(form)
        return '', 202

    return render_template('submit.html', form=form)

@celery.task()
def generate(form):
    ...

1 个答案:

答案 0 :(得分:0)

就像错误告诉你的那样,celery任务正在尝试序列化一个Object。这是不可能的。

相反,您可以序列化request.form

这是未经测试的,但这样的事情应该有效:

class MyForm(FlaskForm):
     name_of_the_file = StringField()
     first_name = StringField()
     number = DecimalField()
     date = DateField()

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    if request.method == 'POST':
        form = MyForm(request.form)

        if form.validate_on_submit():
            generate.delay(request.form)
            return '', 202
    else:
        form = MyForm()

    return render_template('submit.html', form=form)