Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Build a Social Network with Flask Takin' Names Macros

Tyler Noblett
Tyler Noblett
4,951 Points

'str object' has no attribute 'hidden_tag'

I'm able to load the page that says 'Hey', but when I got to add "/register" I get an error. Any thoughts about what I need to change?

jinja2.exceptions.UndefinedError
jinja2.exceptions.UndefinedError: 'str object' has no attribute 'hidden_tag'

Traceback (most recent call last)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
Open an interactive python shell in this frameresponse = self.make_response(self.handle_exception(e))
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/treehouse/workspace/app.py", line 51, in register
return render_template('register.html', form ='form')
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/templating.py", line 128, in render_template
context, ctx.app)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/templating.py", line 110, in _render
rv = template.render(context)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/environment.py", line 969, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/environment.py", line 742, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/_compat.py", line 36, in reraise
raise value.with_traceback(tb)
File "/home/treehouse/workspace/templates/register.html", line 3, in <module>
{{ form.hidden_tag() }}
jinja2.exceptions.UndefinedError: 'str object' has no attribute 'hidden_tag'
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

Here's my code for "register.html"

{% from 'macros.html' import render_field %}
<form method="POST" action ="" class="form">
    {{ form.hidden_tag() }}
    {% for field in form %}
        {{ render_field(field) }}    
    {% endfor %} 
    <button type="submit" id="submit">Register!</button>
</form>

and "app.py"

from flask import (Flask, g, render_template, flash, redirect, url_for)
from flask.ext.login import LoginManager

import forms
import models

DEBUG = True
PORT = 8000
HOST = '0.0.0.0'

app = Flask(__name__)
app.secret_key = 'asdjflaksdfj7q34p987t8g>FDasdfjj;@#$@#jasflkjlsdf'

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

@login_manager.user_loader
def load_user(userid):
    try:
        return models.User.get(models.User.id == userid)
    except models.DoesNotExist:
        return None


@app.before_request
def before_request():
    """Connect to the database before each request"""
    g.db = models.DATABASE
    g.db.connect()


@app.after_request
def after_request(response):
    """Close the database connection after each request"""
    g.db.close()
    return response


@app.route('/register', methods = ('GET', 'POST'))
def register():
    form = forms.RegisterForm()
    if form.validate_on_submit():
        flash("Yay! You registered", "success")
        models.User.create_user(
            username = form.username.data,
            email = form.email.data,
            password = form.password.data
        )
        return redirect(url_for('index'))
    return render_template('register.html', form ='form')


@app.route('/')
def index():
    return "Hey"                       




if __name__ == '__main__':
    models.initialize()
    try:
        models.User.create_user(
            username = 'tylernoblett',
            email = 'Tyler.Noblett@outlook.com',
            password = 'password',
            admin = True
        )
    except ValueError:
        pass
    app.run(debug=DEBUG, host=HOST, port=PORT)
Dmitry Karamin
Dmitry Karamin
10,099 Points

try

form.hidden_tag

instead of

form.hidden_tag()

Can you also post your forms.py file?

Also, put python after the three opening backticks to do the syntax highlighting.

2 Answers

Ahh, sorry, your error was in app.py in your register route. Specifically, you're passing a string 'form' instead of the variable. Try changing to this (change is on the last line):

@app.route('/register', methods = ('GET', 'POST'))
def register():
    form = forms.RegisterForm()
    if form.validate_on_submit():
        flash("Yay! You registered", "success")
        models.User.create_user(
            username = form.username.data,
            email = form.email.data,
            password = form.password.data
        )
        return redirect(url_for('index'))
    return render_template('register.html', form=form)
Tyler Noblett
Tyler Noblett
4,951 Points

ah, you're totally right. Thanks so much!

Tyler Noblett
Tyler Noblett
4,951 Points

Hi Dmitry Karamin - Thanks for your response. I tried your suggestion, and then got this error:

jinja2.exceptions.UndefinedError
jinja2.exceptions.UndefinedError: 'str object' has no attribute 'label'

Traceback (most recent call last)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
Open an interactive python shell in this framereraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/treehouse/workspace/app.py", line 51, in register
return render_template('register.html', form ='form')
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/templating.py", line 128, in render_template
context, ctx.app)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/flask/templating.py", line 110, in _render
rv = template.render(context)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/environment.py", line 969, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/environment.py", line 742, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/_compat.py", line 36, in reraise
raise value.with_traceback(tb)
File "/home/treehouse/workspace/templates/register.html", line 5, in <module>
{{ render_field(field) }}
File "/home/treehouse/workspace/templates/macros.html", line 8, in <module>
{{ field(placeholder = field.label.text) }}
File "/usr/local/pyenv/versions/3.5.0/lib/python3.5/site-packages/jinja2/environment.py", line 397, in getattr
return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'str object' has no attribute 'label'

As far as I can tell, the code referenced in "register.html" and "macros.html" were what Kenneth typed in, but I could be wrong. Here's the code for "macros.html"

{% macro render_field(field) %}    
    <div class="field">
        {% if field.errors %}
            {% for error in field.errors %}
                <div class="notification error">{{ error }}</div>
            {% endfor %}
        {% endif %}
        {{ field(placeholder = field.label.text) }}
    </div>
{% endmacro %}
Tyler Noblett
Tyler Noblett
4,951 Points

Iain Simmons will do!

from flask_wtf import Form
from wtforms import StringField, PasswordField
from wtforms.validators import (DataRequired, Regexp, ValidationError, Email,
                               Length, EqualTo)

from models import User

def name_exists(form, field):
    if User.select().where(User.username == field.data).exists():
        raise ValidationError('User with that name already exists.')

def email_exists(form, field):
    if User.select().where(User.email == field.data).exists():
        raise ValidationError('User with that email already exists.')


class RegisterForm(Form):
    username = StringField(
        'Username',
        validators=[
            DataRequired(),
            Regexp(
                r'^[a-zA-Z0-9_]+$',
                message = ("Username should be one word, letters, "
                           "numbers, and underscores only.")
                ),
                name_exists
        ])    
    email = StringField(
        'Email',
        validators=[
            DataRequired(),
            Email(),
            email_exists
        ])
    password = PasswordField(
        'Password',
        validators = [
            DataRequired(),
            Length(min=7),
            EqualTo('password2', message = 'Passwords must match')
        ])
    password2 = PasswordField(
        'Confirm Password',
        validators = [DataRequired()]
    )

class LoginForm(Form):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])]