2013-05-08 22 views
6

Tôi đang sử dụng WTForms lần đầu tiên. Sử dụng WTForms để xác nhận yêu cầu POST trong Tornado Dưới đây là hình thức của tôi forms.pyTornado và WTForms

class UserForm(Form): 
    user = TextField('user', [validators.Length(min=23, max=23)]) 

Trong xử lý tonado Tôi có

def post(self): 
    form = UserForm(self.request.body) 

Thông báo lỗi tôi nhận được là: formdata phải là một multidict-type wrapper hỗ trợ phương thức 'getlist' "

Tôi làm cách nào để thực hiện công việc này?

Trả lời

7

wtforms-lốc xoáy 0.0.1

WTForms phần mở rộng cho Tornado.

pip install wtforms-tornado 

WTForms-Tornado

2

Bạn sẽ cần một đối tượng có thể dịch đối tượng dạng Tornado thành thứ gì đó mà WTForms mong đợi. Tôi sử dụng này:

class TornadoFormMultiDict(object): 
"""Wrapper class to provide form values to wtforms.Form 

This class is tightly coupled to a request handler, and more importantly one of our BaseHandlers 
which has a 'context'. At least if you want to use the save/load functionality. 

Some of this more difficult that it otherwise seems like it should be because of nature 
of how tornado handles it's form input. 
""" 
def __init__(self, handler): 
    # We keep a weakref to prevent circular references 
    # This object is tightly coupled to the handler... which certainly isn't nice, but it's the 
    # way it's gonna have to be for now. 
    self.handler = weakref.ref(handler) 

@property 
def _arguments(self):   
    return self.handler().request.arguments 

def __iter__(self): 
    return iter(self._arguments) 

def __len__(self): 
    return len(self._arguments) 

def __contains__(self, name): 
    # We use request.arguments because get_arguments always returns a 
    # value regardless of the existence of the key. 
    return (name in self._arguments) 

def getlist(self, name): 
    # get_arguments by default strips whitespace from the input data, 
    # so we pass strip=False to stop that in case we need to validate 
    # on whitespace. 
    return self.handler().get_arguments(name, strip=False) 

def __getitem__(self, name): 
    return self.handler().get_argument(name) 

Sau đó, trong xử lý cơ sở của bạn, bạn muốn làm điều gì đó như:

self.form = TornadoFormMultiDict(self) 

Lưu ý: Tôi nghĩ rằng đây chuyển thể từ một mailing list topic on this subject.

0

tôi không tìm thấy việc thay thế một hình thức html cơ bản chứa trong một mẫu với một WTForms Tornado hình như trực giác như tôi có thể hy vọng.

Dưới đây là một ví dụ về hình thức rất đơn giản sử dụng wtforms-tornado:

Mẫu:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 

<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>A Simple Form</title> 
    <meta name="description" content="Submit Track to Infinite Glitch"> 
</head> 
<body> 
<p><h1>Submit Info</h1></p> 
<form enctype="multipart/form-data" action="/simple" method="post"> 
{{ form.name }}<br/> 
{{ form.email }}<br/> 
{{ form.message }}<br/> 
<input type="submit"/> 
</form> 
</body> 
</html>  

Mã ứng dụng:

import wtforms 
from wtforms_tornado import Form 

class EasyForm(Form): 
      name = wtforms.TextField('name', validators=[wtforms.validators.DataRequired()], default=u'test') 
      email = wtforms.TextField('email', validators=[wtforms.validators.Email(), wtforms.validators.DataRequired()]) 
      message = wtforms.TextAreaField('message', validators=[wtforms.validators.DataRequired()]) 

class SimpleForm(tornado.web.RequestHandler): 
    def get(self): 
     form = EasyForm() 
     self.write(templates.load("simpleform.html").generate(compiled=compiled, form=form)) 

    def post(self): 
     form = EasyForm(self.request.arguments) 
     details = ''; 
     if form.validate(): 
      for f in self.request.arguments: 
       details += "<hr/>" + self.get_argument(f, default=None, strip=False) 
      self.write(details) 
     else: 
      self.set_status(400) 
      self.write(form.errors) 

if __name__ == "__main__": 

    application = tornado.web.Application(
     tornadio2.TornadioRouter(SocketConnection).apply_routes([ 
      (r"/simple", SimpleForm), 
     ]), 
    ) 

    application.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 
+0

Hi, bạn có thể hoàn thành việc nhập khẩu mất tích từ 'tự .write (templates.load ("simpleform.html"). generate (biên dịch = biên dịch, form = form)) 'để mã trở thành runnable? – kardaj

+0

Không sử dụng Tornado lúc này vì vậy sẽ phải kiểm tra điều này một thời gian khác. – MikeiLL