WTForms上的UnicodeDecodeError

时间:2015-08-10 22:54:56

标签: python utf-8 flask wtforms

这个错误导致我在没有任何解决方案的情况下进行了数小时的研究。

This is the traceback on GAE:
Traceback (most recent call last):
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask_restful/__init__.py", line 270, in error_router
    return original_handler(e)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/site/decorators.py", line 36, in decorated_view
    return func(*args, **kwargs)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/site/views.py", line 134, in publish_news
    return render_template('news.html', post=news, form=form)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/templating.py", line 128, in render_template
    context, ctx.app)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/flask/templating.py", line 110, in _render
    rv = template.render(context)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/jinja2-2.6/jinja2/environment.py", line 894, in render
    return self.environment.handle_exception(exc_info, True)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/site/templates/news.html", line 1, in top-level template code
    {% extends "base.html" %}
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/site/templates/base.html", line 93, in top-level template code
    {% block body %}
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/site/templates/news.html", line 55, in block "body"
    {{ form.tweet }}
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/wtforms/fields/core.py", line 133, in __html__
    return self()
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/wtforms/fields/core.py", line 149, in __call__
    return self.meta.render_field(self, kwargs)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/wtforms/meta.py", line 53, in render_field
    return field.widget(field, **render_kw)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/wtforms/widgets/core.py", line 257, in __call__
    escape(text_type(field._value()), quote=False)
  File "/base/data/home/apps/s~xxx/1-0-38.386228028384623065/lib/wtforms/fields/core.py", line 529, in _value
    return text_type(self.data) if self.data is not None else ''
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 60: ordinal not in range(128)

似乎{{ form.tweet }}导致了这一点。

class PublishForm(Form):
    tweet = TextAreaField('tweet', [validators.DataRequired(), validators.Length(-1, 123, 'Max 140 chars allowed')])

视图是这样的:

# coding: utf8

def publish_news(news_id):
    news = ndb.Key(urlsafe=news_id).get()
    form = PublishForm()
    if form.validate_on_submit():
        ...
        news.put()
        return redirect(url_for('list_news'))
    if not form.tweet.data:
        tweet = u''
        for s in news.slug_list:
            if '-' in s:
                continue
            tweet = tweet + u'#' + s + u', '
        tweet = tweet[:-2].encode('utf-8')
        head_line = news.head_line.encode('utf-8')
        max_tweet_length = 140 - (len(tweet) + 4 + 23)  # three dots + space + url
        tweet = head_line[:max_tweet_length] + '... [URL] ' + tweet
        form.tweet.data = tweet
    return render_template('news.html', post=news, form=form)

它在GET期间崩溃,从未进入POST。我能错过什么?

1 个答案:

答案 0 :(得分:3)

我不得不改变这一行

form.tweet.data = tweet

form.tweet.data = tweet.decode('utf-8')

记得回到POST时,你必须再次.encode('utf-8')