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!

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, Controlling Sessions Challenge

Challenge Task 2 of 2

Now add a view named logout() with "/logout" as its route. This view should log the user out and then redirect to "/login". You'll need to import logout_user, redirect, and probably url_for.

Link to challenge:

http://teamtreehouse.com/library/build-a-social-network-with-flask/takin-names/controlling-sessions

I got through the first part of the challenge:

Challenge Task 1 of 2

Currently, "/secret" isn't protected from anonymous users. Mark it so it requires users to be logged in. You'll need to import login_required.

..by changing this line:

from flask.ext.login import LoginManager, login_user, current_user

..to this line:

from flask.ext.login import (LoginManager, login_user, logout_user,
                             login_required)

Then changing this:

@app.route('/secret')
def secret():
    return "I should only be visible to logged-in users"

..to this;

@app.route('/secret')
@login_required
def secret():
    return "I should only be visible to logged-in users"

So far so good (but the first challenge is just designed to "lure you in...")

The for the second part the 'from' lines at the top need to be updated to:

from flask import (Flask, g, render_template, flash, redirect, url_for)
from flask.ext.bcrypt import check_password_hash
from flask.ext.login import (LoginManager, login_user, logout_user,
                             login_required)

What about the rest of the challenge question:

..add a view named logout() with "/logout" as its route. This view should log the user out and then redirect to "/login".

The downloads for this project has a folder called "S3V1" with an app.py that has this code fragment:

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash("You've been logged out! Come back soon!", "success")
    return redirect(url_for('index'))

Of course it doesn't work:

Bummer! Try again!

Here is the output.html:

Traceback (most recent call last): File "7485a6e7-3946-432d-899b-43f28b91bc49.py", line 146, in """) File "", line 29, in File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 774, in get return self.open(*args, **kw) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/testing.py", line 108, in open follow_redirects=follow_redirects) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 742, in open response = self.run_wsgi_app(environ, buffered=buffered) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 659, in run_wsgi_app rv = run_wsgi_app(self.application, environ, buffered=buffered) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 867, in run_wsgi_app app_iter = app(environ, start_response) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1836, in call return self.wsgi_app(environ, start_response) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1473, in full_dispatch_request rv = self.preprocess_request() File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1666, in preprocess_request rv = func() File "", line 31, in before_request NameError: name 'current_user' is not defined

Yeah, that told me EXACTLY where the problem is (NOT!)

Also tried different variations including:

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('login.html'))

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('/login.html'))

@app.route('/logout')
def logout():
    logout_user()
    return redirect('/login.html')

@app.route('/logout')
def logout():
    logout_user()
    return render_template('login.html', form=form)

@app.route('/logout')
def logout():
    logout_user()
    return render_template('/login.html', form=form)

Any ideas? Suggestions?

4 Answers

Hi James

the code looks fine but should'nt you be redirecting to login??

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))# instead of return redirect(url_for('index'))
Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Your code passes for me. Did this address your problem, james white?

Thanks Andreas and Kenneth, but no, it's still not passing with this code:

from flask import (Flask, g, render_template, flash, redirect, url_for)
from flask.ext.bcrypt import check_password_hash
from flask.ext.login import (LoginManager, login_user, logout_user,
                             login_required)

import forms
import models

app = Flask(__name__)
app.secret_key = 'this is our super secret key. do not share it with anyone!'
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.select().where(
            models.User.id == int(userid)
        ).get()
    except models.DoesNotExist:
        return None


@app.before_request
def before_request():
    g.db = models.DATABASE
    g.db.connect()
    g.user = current_user


@app.after_request
def after_request(response):
    g.db.close()
    return response


@app.route('/register', methods=('GET', 'POST'))
def register():
    form = forms.SignUpInForm()
    if form.validate_on_submit():
        models.User.new(
            email=form.email.data,
            password=form.password.data
        )
        flash("Thanks for registering!") 
    return render_template('register.html', form=form)


@app.route('/login', methods=('GET', 'POST'))
def login():
    form = forms.SignUpInForm()
    if form.validate_on_submit():
        try:
            user = models.User.get(
                models.User.email == form.email.data
            )
            if check_password_hash(user.password, form.password.data):
                login_user(user)
                flash("You're now logged in!")
            else:
                flash("No user with that email/password combo")
        except models.DoesNotExist:
              flash("No user with that email/password combo")
    return render_template('register.html', form=form)

@app.route('/secret')
@login_required
def secret():
    return "I should only be visible to logged-in users"

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

Here's the screenshot I uploaded to imgur:

alt text

The latest Preview "output.html" reads:

Traceback (most recent call last): File "6d1170b9-01d2-4bf3-8409-f9a6ecdb87cd.py", line 146, in """) File "", line 29, in File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 774, in get return self.open(*args, **kw) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/testing.py", line 108, in open follow_redirects=follow_redirects) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 742, in open response = self.run_wsgi_app(environ, buffered=buffered) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 659, in run_wsgi_app rv = run_wsgi_app(self.application, environ, buffered=buffered) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/werkzeug/test.py", line 867, in run_wsgi_app app_iter = app(environ, start_response) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1836, in call return self.wsgi_app(environ, start_response) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1820, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1403, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise raise value File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1473, in full_dispatch_request rv = self.preprocess_request() File "/usr/local/pyenv/versions/3.4.1/lib/python3.4/site-packages/flask/app.py", line 1666, in preprocess_request rv = func() File "", line 30, in before_request NameError: name 'current_user' is not defined

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Looking at your original post, you removed current_user from the imports. Since that's missing, the second step, where we log out the current user, can't run. Add that import back in and your code passes for me.

Wow!

So it was not leaving in "current_user" (present in the original 'from flask.ext.login import' line for task 1) that stopped me from completing task 2?!

So the acceptable (passing) 'from' lines (for both challenges) should be:

from flask import (Flask, g, render_template, flash, redirect, url_for)
from flask.ext.bcrypt import check_password_hash
from flask.ext.login import (LoginManager, login_user, logout_user,
                             current_user, login_required)

.

I wonder why (then) it let me pass Task 1 of 2 with 'current_user' missing from the bottom 'from' line

and only "woke up" to the fact that it had gone away (was missing) when I got to Task 2?


As a final thought:

Notice though that BOTH of the output.html text passages above

have this at the bottom:

'NameError: name 'current_user' is not defined '

So all that gobbledygook actually was trying to tell me something

(if only I had known how to 'translate' it).

Chai Chong Teh
Chai Chong Teh
25,709 Points
from flask import Flask, g, render_template, flash, url_for, redirect
from flask.ext.bcrypt import check_password_hash
from flask.ext.login import LoginManager, login_user, current_user, login_required, logout_user

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('/login.html'))

Somewhat, I just can't make it work.

Chai Chong Teh
Chai Chong Teh
25,709 Points

I edited this line...

return redirect(url_for('/login.html'))

to

return redirect(url_for('/login'))

does the file extension really matters?