简体   繁体   中英

AttributeError: 'NoneType' object has no attribute 'name'

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())

template:

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

error:

AttributeError: 'NoneType' object has no attribute 'name'


However this works, but i need a function inside the class 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)

Your forms() method doesn't return anything:

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

The default is to return None in that case. Since you pass the result of Form().forms() to your template, you end up with form=None .

If you need to set name on the Form instance only after calling a method on it, then do so in that method:

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()

where, for a wtforms field, you need to bind the field to the form before you can use it. Normally, the framework takes care of this for you.

Then call that method separately:

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

If you want to set an instance variable, you have to use self . Otherwise it's just a local variable that goes away when the function ends.

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

you need a Form object with a name attribute. The second version works because it creates a Form object, with a class variable called name. The first version doesn't, because it is returning a string with the result of form.forms(), not the object itself.

You want this:

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

then later, use the same form as before:

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

If you need to CHANGE self.name later, then add a function that does the above again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM