使用 GAE(和 WTForms)进行 HTTP 发布

发布于 2024-12-13 18:35:22 字数 7378 浏览 3 评论 0原文

您好,当使用 blobstoreuploadhandler 完成帖子并且最好还使用 i18n 本地化消息进行验证时,如何使用 WTForms 获取 HTTP 帖子中的变量? 这是我的代码不起作用:

class AdForm(Form):
    name = TextField(_('Name'))
    title = TextField(_('title'))
    text = TextAreaField(_('Text'),widget=TextArea())
    phonenumber = TextField(_('Phone number'))
    phonenumberhide = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'))
    password = PasswordField(_('Password'))
    email = TextField(_('Email'))

当我尝试访问通过表单发布的数据时,数据结果为 None

form = AdForm(data=self.request.POST)
if form.title:
  logging.info('getting title:'+form.title.data)
  ad.title = form.title.data
  ad.save()

上面不会将任何内容保存到数据存储区,这是它所在的模板来自

  <div class="labelform">
         <div class="labelform" style="clear:left;">
    <label> {% filter capitalize %}{% trans %}title{% endtrans %}{% endfilter %}:</label>
  </div>
  </div>
  </td><td>
{{ form.title }}{% if form.title.errors %}
        <ul class="errors">{% for error in form.title.errors %}<li>{{ error }}</li>{% endfor %}</ul>
    {% endif %}

你能帮我吗? WTForms 手册中有关于 appengine 的内容 但我找不到有效的例子。

更新

我添加了验证测试,但仍然无法访问变量:

logging.info('getting requests')
if form.validate():
  if form.title:
    logging.info('getting title:'+form.title.data)
    ad.title = form.title.data
    ad.save()
    ad.put()

记录输出:

INFO 2011-11-05 23:17:24,653 main.py:1504] 获取请求 INFO
2011-11-05 23:17:24,653 main.py:1507] 获取标题:

更新 2

我删除了 WTForms 依赖项,但它仍然无法正常工作。 logging.info('getting data:'+ self.request.get('title', '0')) 行仅输出 0,即使该表单只是常规的 http post 表单:

 <form action="{{form_url}}" name="upload" method="post" enctype="multipart/form-data" accept-charset="utf-8">

< strong>更新3

这个最小的配置没有WTForms,也没有Jinja,所以当这个简单的例子与webapp2和python 2.7一起工作时,它可能与Jinja有关,我将在其中逐行添加错误代码进行故障排除:

class GuestPage(BaseHandler):
    def get(self):
        self.response.out.write("""
          <html>
            <body>
              <form action="/sign" method="post">
                <div><textarea name="content" rows="3" cols="60"></textarea></div>
                <div><input type="submit" value="Sign Guestbook"></div>
              </form>
            </body>
          </html>""")


class Guestbook(BaseHandler, I18NHandler, blobstore_handlers.BlobstoreUploadHandler):
    csrf_protect = False

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')


app = webapp2.WSGIApplication([        ('/guest', GuestPage),
                                      ('/sign', Guestbook),

...

更新 4

我回到了基础,正在使用 Jinja,所以我想我只是在此示例的基础上进行构建,看看它在哪里出现问题:

class GuestPage(BaseHandler):
    def get(self):
    self.render_jinja('form_jinja')

class Guestbook(BaseHandler, I18NHandler, blobstore_handlers.BlobstoreUploadHandler):
    csrf_protect = False

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')

更新 5

我可以重现这个最小示例的错误无法访问 http post 变量:

class GuestPage(webapp2.RequestHandler):
    def get(self):

        self.response.out.write("""
          <html>
            <body>
              <form action=" """ +blobstore.create_upload_url('/sign')+ """ " method="post">
                <div><textarea name="content" rows="3" cols="60"></textarea></div>
                <div><input type="submit" value="Sign Guestbook"></div>
              </form>
            </body>
          </html>""")


class Guestbook(blobstore_handlers.BlobstoreUploadHandler):

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')


app = webapp2.WSGIApplication([       ('/guest', GuestPage),
                                      ('/sign', Guestbook),

更新 6

从带有 blobstoreuploadhandler 的留言簿示例代码中,我可以在生产服务器上上传一个文件,这样我就可以制作一个使用的工作示例我的 blobstoreuploadhandler将尝试为我的用例进行构建。

更新 7

我可以获得原始代码,以便除了 blob 传输之外一切正常。我怀疑 dev_appserver 和我发布到 google appengine 组的生产之间存在差异。我们将看看进展如何。

更新8 这是添加 WTForms 后没有任何效果的另一个常见用法:

    logging.info('getting data:'+ self.request.get('title', '0'))
    logging.info('http post data:'+ str(self.request.post))
    form = AdForm(formdata=self.request.data)
    logging.info('populated form')
    logging.info('form data:' + str(form.formdata))
    if form.validate():
      if form.title:
        logging.info('getting title:'+str( form.get('title') ) )
        ad.title = form.title.data      ad.save()       ad.put()
      if form.text:
        logging.info('getting text:' +str(form.text))
        ad.text = form.text.data
      if self.request.get('currency'):
        ad.currency = self.request.get('currency')
      if self.request.get('cg'):
        ad.category = form.cg.data
      if self.request.get('company_ad') == '1':
        ad.company_ad = True
      ad.put()
    else:
      logging.info('form did not validate')
except Exception, ex:
    logging.info('there occured exception %s', str(ex))

INFO 2011-11-09 12:11:50,868 main.py:1385] 获取数据:测试信息 2011-11-09 12:11:50,868 main.py:1409]发生异常帖子

2011-11-09 12:11:50,868 main.py:1409] 更新 9

最后,表单填充它只是不验证。谢谢肖恩提供的信息让我走得更远。现在我已经填充了表单对象,没有任何异常,但是当我尝试验证时会发生异常:

logging.info('getting data:'+ self.request.get('title', '0'))
form = AForm(self.request.POST)
logging.info('populated form')
if form.validate():
  logging.info('validated form')

上面的代码正在记录输出:

INFO     2011-11-11 08:03:59,913 main.py:1387] getting data:TEST
INFO     2011-11-11 08:03:59,914 main.py:1390] populated form
INFO     2011-11-11 08:03:59,914 main.py:1412] there occured exception 'builtin_function_or_method' object is not iterable

异常是什么意思?

我的表格类是

class AForm(Form):
    name = TextField(_('Name'))
    title = TextField(_('title'))
    text = TextAreaField(_('Text'),widget=TextArea())
    phonenumber = TextField(_('Phone number'))
    phonenumberhide = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'))
    password = PasswordField(_('Password'))
    email = TextField(_('Email'))  
    category  = SelectField(choices=categories.keys)

Hi how can I get the variables in a HTTP post with WTForms when the post is done with a blobstoreuploadhandler and preferably also with i18n localized messages for validation?
This is my code that is not working:

class AdForm(Form):
    name = TextField(_('Name'))
    title = TextField(_('title'))
    text = TextAreaField(_('Text'),widget=TextArea())
    phonenumber = TextField(_('Phone number'))
    phonenumberhide = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'))
    password = PasswordField(_('Password'))
    email = TextField(_('Email'))

When I try to access the data posted via the form the data turns out as None:

form = AdForm(data=self.request.POST)
if form.title:
  logging.info('getting title:'+form.title.data)
  ad.title = form.title.data
  ad.save()

The above does not save anything to the datastore and this is the template where it's coming from

  <div class="labelform">
         <div class="labelform" style="clear:left;">
    <label> {% filter capitalize %}{% trans %}title{% endtrans %}{% endfilter %}:</label>
  </div>
  </div>
  </td><td>
{{ form.title }}{% if form.title.errors %}
        <ul class="errors">{% for error in form.title.errors %}<li>{{ error }}</li>{% endfor %}</ul>
    {% endif %}

Can you help me? There's something in the WTForms manual about appengine but I couldn't find a working example.

Update

I added validation tests and I still can't access the variables:

logging.info('getting requests')
if form.validate():
  if form.title:
    logging.info('getting title:'+form.title.data)
    ad.title = form.title.data
    ad.save()
    ad.put()

Logging output:

INFO 2011-11-05 23:17:24,653 main.py:1504] getting requests INFO
2011-11-05 23:17:24,653 main.py:1507] getting title:

Update 2

I removed the WTForms dependence and it is still not working. The line logging.info('getting data:'+ self.request.get('title', '0')) only outputs 0 even though the form is just a regular http post form:

 <form action="{{form_url}}" name="upload" method="post" enctype="multipart/form-data" accept-charset="utf-8">

Update 3

This minimal config with no WTForms and no Jinja works so it's probably something with Jinja when this bare-bones example works with webapp2 and python 2.7 where I'm going to add the faulty code line by line to troubleshoot:

class GuestPage(BaseHandler):
    def get(self):
        self.response.out.write("""
          <html>
            <body>
              <form action="/sign" method="post">
                <div><textarea name="content" rows="3" cols="60"></textarea></div>
                <div><input type="submit" value="Sign Guestbook"></div>
              </form>
            </body>
          </html>""")


class Guestbook(BaseHandler, I18NHandler, blobstore_handlers.BlobstoreUploadHandler):
    csrf_protect = False

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')


app = webapp2.WSGIApplication([        ('/guest', GuestPage),
                                      ('/sign', Guestbook),

...

Update 4

My back to basics is working with Jinja so I suppose I just build on this example and see where it breaks:

class GuestPage(BaseHandler):
    def get(self):
    self.render_jinja('form_jinja')

class Guestbook(BaseHandler, I18NHandler, blobstore_handlers.BlobstoreUploadHandler):
    csrf_protect = False

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')

Update 5

I can reproduce the error with this minimal example that can't access the http post variable:

class GuestPage(webapp2.RequestHandler):
    def get(self):

        self.response.out.write("""
          <html>
            <body>
              <form action=" """ +blobstore.create_upload_url('/sign')+ """ " method="post">
                <div><textarea name="content" rows="3" cols="60"></textarea></div>
                <div><input type="submit" value="Sign Guestbook"></div>
              </form>
            </body>
          </html>""")


class Guestbook(blobstore_handlers.BlobstoreUploadHandler):

    def post(self):
        self.response.out.write('<html><body>You wrote:<pre>')
        self.response.out.write(self.request.get('content'))
        self.response.out.write('</pre></body></html>')


app = webapp2.WSGIApplication([       ('/guest', GuestPage),
                                      ('/sign', Guestbook),

Update 6

From the guestbook example code with blobstoreuploadhandler I can upload a file on the production server so I could make a working example that uses the blobstoreuploadhandler that I will try to build on for my use case.

Update 7

I could get my original code so that everything works except the blob transfer. I suspect a diff between dev_appserver and production that I posted to the google appengine group about. We'll see how it progresses.

Update 8
Here's another common use how nothing works when you add WTForms:

    logging.info('getting data:'+ self.request.get('title', '0'))
    logging.info('http post data:'+ str(self.request.post))
    form = AdForm(formdata=self.request.data)
    logging.info('populated form')
    logging.info('form data:' + str(form.formdata))
    if form.validate():
      if form.title:
        logging.info('getting title:'+str( form.get('title') ) )
        ad.title = form.title.data      ad.save()       ad.put()
      if form.text:
        logging.info('getting text:' +str(form.text))
        ad.text = form.text.data
      if self.request.get('currency'):
        ad.currency = self.request.get('currency')
      if self.request.get('cg'):
        ad.category = form.cg.data
      if self.request.get('company_ad') == '1':
        ad.company_ad = True
      ad.put()
    else:
      logging.info('form did not validate')
except Exception, ex:
    logging.info('there occured exception %s', str(ex))

INFO 2011-11-09 12:11:50,868 main.py:1385] getting data:TEST INFO
2011-11-09 12:11:50,868 main.py:1409] there occured exception post

Update 9

Finally the form populates it just doesn't validate. Thank you Sean for the info that got me further. Now I get past populated the form object with no exception but the exception occurs when I try to validate:

logging.info('getting data:'+ self.request.get('title', '0'))
form = AForm(self.request.POST)
logging.info('populated form')
if form.validate():
  logging.info('validated form')

The above code is logging the output:

INFO     2011-11-11 08:03:59,913 main.py:1387] getting data:TEST
INFO     2011-11-11 08:03:59,914 main.py:1390] populated form
INFO     2011-11-11 08:03:59,914 main.py:1412] there occured exception 'builtin_function_or_method' object is not iterable

What does the exception mean?

My form class is

class AForm(Form):
    name = TextField(_('Name'))
    title = TextField(_('title'))
    text = TextAreaField(_('Text'),widget=TextArea())
    phonenumber = TextField(_('Phone number'))
    phonenumberhide = BooleanField(_('Display phone number on site'))
    price = TextField(_('Price'))
    password = PasswordField(_('Password'))
    email = TextField(_('Email'))  
    category  = SelectField(choices=categories.keys)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月如刀 2024-12-20 18:35:22

我对 WTForm 一无所知,但我猜想像 Django 表单一样,您需要先调用验证函数才能访问数据。在本例中,它是 form.validate()

form = AdForm(formdata=self.request.POST)
if form.validate():
    ad.title = form.title.data

I don't know anything about WTForm, but I'd guess that like Django forms, you need to call the validation function before you can access the data. In this case, it's form.validate():

form = AdForm(formdata=self.request.POST)
if form.validate():
    ad.title = form.title.data
抽个烟儿 2024-12-20 18:35:22

丹尼尔实际上您需要传递给表单的不是 data=self.request.POST 而是 formdata 而不是 data
http://wtforms.simplecodes.com/docs/dev/forms .html#the-form-class

希望它对所有像我一样匆忙浏览文档的人有用

Daniel actually it is not data=self.request.POST that you need to pass to the form but formdata instead of data
http://wtforms.simplecodes.com/docs/dev/forms.html#the-form-class

hope it will be usefull for all those who rushed through the doc as i did

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文