2013-10-24 5 views
0
class Form(Form): 
    def forms(self): 
     name = TextField('name', validators=[Required()]) 

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     form = Form() 
     self.render('index.html', form=form.forms()) 

шаблона:AttributeError: объект 'NoneType' не имеет 'имя' атрибут

<form method="post" action="/test"> 
    {% raw form.name(type='text') %} 
</form> 

ошибки:

AttributeError: объект 'NoneType' не имеет 'имя' атрибут


Однако это работает, но мне нужна функция внутри класса Form:

class Form(Form): 
     name = TextField('name', validators=[Required()]) 

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     form = Form() 
     self.render('index.html', form=form) 
+0

Возможно, вы используете 'self.name = ...' в 'Form'. –

+1

_ "Однако это работает, но мне нужна функция внутри класса Form" _ Почему, по-вашему, вам это нужно? –

ответ

1

Если вы хотите установить переменную экземпляра, вы должны использовать self. В противном случае это просто локальная переменная, которая исчезает, когда функция заканчивается.

def forms(self): 
    self.name = TextField('name', validators=[Required()]) 
+0

точно такая же ошибка. – anvd

+0

Это не сработает, так как эта функция все равно вернет 'None'. – Esenti

+0

@ Esenti, учитывая, как это было написано, я не был уверен, что он должен был что-то вернуть. Я отредактирую что-то немного более вероятно, чтобы работать, учитывая мои знания о торнадо. –

4

Ваш метод forms() не возвращает ничего:

class Form(Form): 
    def forms(self): 
     name = TextField('name', validators=[Required()]) 

по умолчанию является возвращение None в этом случае. Так как вы сдаете результат Form().forms() в свой шаблон, вы получите form=None.

Если вам необходимо установить name на экземпляре Form только после вызова метода на нем, то сделать это в этом методе:

class Form(Form): 
    def forms(self): 
     name = TextField('name', validators=[Required()]) 
     self.name = name.bind(form=self, name='name', 
           prefix=self._prefix, 
           translations=self._get_translations()) 
     self._fields['name'] = self.name 
     self.process() 

где для wtforms поля, вам нужно связывать с поле до формы, прежде чем вы сможете его использовать. Как правило, структура заботится об этом для вас.

Затем вызовите этот метод отдельно:

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     form = Form() 
     form.forms() 
     self.render('index.html', form=form) 
+0

извините, но теперь TypeError: объект «UnboundField» не может быть вызван – anvd

+0

@anvd: Какая форма рамки это?Скорее всего, обработчик '__init__' связывает поля формы при создании экземпляра формы и с помощью метода, который вы обошли это. ** Почему ** вам нужен отдельный метод? –

+0

wtforms. Я думаю об отдельном методе, потому что мне нужно передать список кортежей этому классу. – anvd

1

вам нужна форма объекта с атрибутом имени. Вторая версия работает, потому что она создает объект Form, с переменной класса name. Первая версия этого не делает, потому что она возвращает строку с результатом формы.forms(), а не сам объект.

Вы хотите:

class Form(object): 
    def __init__(self): 
     self.name = TextField('name', validators=[Required()]) 

потом, использовать ту же форму, как и раньше:

self.render('index.html', form=form) 

Если вам нужно изменить self.name позже, а затем добавить функцию, которая делает выше еще раз.

+0

Такая же ошибка UnboundField. спасибо – anvd

+0

Ой, подождите ... ответ очевиден: вы не можете подклассифицировать класс из себя. Ред. Скажите, если это сработает? –

+0

Извините, но нет. такая же ошибка. Объект UnboundField не может быть вызван – anvd

Смежные вопросы