Flask AttributeError: HTMLString does not have '__call__' attribute

I created a macro to handle form errors as follows:

{% macro render_field_with_errors(field) %} <p> {{ field.label }} {{ field(**kwargs)|safe }} {% if field.errors %} <ul> {% for error in field.errors %} <li style="color: red;">{{ error }}</li> {% endfor %} </ul> {% endif %} </p> {% endmacro %} {% macro render_field(field) %} <p>{{ field(**kwargs)|safe }}</p> {% endmacro %} 

My forms.py looks like this:

 from flask.ext.wtf import Form, TextField, BooleanField, PasswordField, RadioField, SelectMultipleField from flask.ext.wtf import Required class LoginForm(Form): username = TextField('email', validators = [Required()]) password = PasswordField('password', validators=[Required()]) remember_me = BooleanField('remember_me', default = False) 

My login form is as follows:

 <!-- Login form --> {% from "includes/_formhelpers.html" import render_field_with_errors %} <form method="POST" action="/login" focus="first"> <div class="span5"> {{ login_form.hidden_tag() }} {{ render_field_with_errors(login_form.username(placeholder="Username / Email", class="span10")) }} <br> {{ render_field_with_errors(login_form.password(placeholder="Password", class="span10")) }} <br> <div class="qp-log"> {{ render_field_with_errors(login_form.remember_me(class="qp-login", value="remember_me")) }} Remember Me <br> <button type="submit" class="btn qp-btn" style="height:30px;width:56px;">Login</button> <button type="Reset" class="btn">Clear</button> </div> <div class="qp-pass"> Forgot Password? <a href ="#">click here</a> </div> </div> <div class="span2"> <br> <br> <br> &nbsp; <img src="{{ url_for('static', filename='img/or_icon.gif') }}"> </div> <div class="span5"> <center> <br> <button class="btn btn-facebook"> <small>Connect with</small> <big> Facebook </big> </button> <h4> or </h4> <button type="Submit" class="btn qp-btn"> <a href="signup.html" style="color:white;">Sign Up for Free</a> </button> </center> </div> </form> <!-- Form End --> 

I get the following error:

 Traceback (most recent call last): File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__ return self.wsgi_app(environ, start_response) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app response = self.full_dispatch_request() File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request rv = self.dispatch_request() File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/home/rahul/git/webapp/webapp/routes.py", line 14, in index return render_template("public/index.html", login_form=login_form)#, registration_form=registration_form) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/templating.py", line 125, in render_template context, ctx.app) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/flask/templating.py", line 107, in _render rv = template.render(context) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render return self.environment.handle_exception(exc_info, True) File "/home/rahul/git/webapp/venv/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception reraise(exc_type, exc_value, tb) File "/home/rahul/git/webapp/webapp/templates/public/index.html", line 1, in top-level template code {% extends "public/base.html" %} File "/home/rahul/git/webapp/webapp/templates/public/base.html", line 1, in top-level template code {% extends 'layout.html' %} File "/home/rahul/git/webapp/webapp/templates/layout.html", line 35, in top-level template code {% block content %}{% endblock %} File "/home/rahul/git/webapp/webapp/templates/public/index.html", line 4, in block "content" {% include 'public/login.html' %} File "/home/rahul/git/webapp/webapp/templates/public/login.html", line 6, in top-level template code {{ render_field_with_errors(login_form.username(placeholder="Username / Email", class="span10")) }} File "/home/rahul/git/webapp/webapp/templates/includes/_formhelpers.html", line 3, in template {{ field.label }} {{ field(**kwargs)|safe }} AttributeError: 'HTMLString' object has no attribute '__call__' 

I don’t understand what is wrong in the code? If I remove the macro from the html file and instead enable a loop to handle errors in the html form, it works fine. Which I think the placeholder and class are included in the element that causes the error, but don’t know why?

+4
source share
1 answer

I had a similar problem lately, I believe the problem is this template in login.html

  {{ render_field_with_errors(login_form.password(placeholder="Password", class="span10")) }} 

you pass the placeholder and class to the login form, which at the moment is just part of the html created by wtf. If I try this in my version of the flask, I get exactly the same error, even hard, the rest of the code is different. If I pass the placeholder and class inside the helper, the error will disappear:

 {{ field(class="span10",placeholder="Password",**kwargs)|safe }} 

If you cannot pass common placeholders and classes in the helper, you can always specify them in the template

 <div class=span10> {{render_field_with_errors(loginForm.password) }} </div> 

UPDATE: Actually, I checked it again, and you can also do it like this:

 {{ render_field_with_errors(login_form.password,placeholder="Password", class="span10") }} 

It makes sense - you pass the keyword arguments to the field. You do not pass it a function with arguments that it cannot handle, but just a few keyword arguments. Hope this helps.

+13
source

Source: https://habr.com/ru/post/1496112/


All Articles