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 Tacocat Challenge Tacocat!

Build a Social Network with Flask

Fill out the files with your finished code to pass the code challenge. Be sure to remove any app.run() calls.

It keeps saying bumber try again. Please Help the challenge video link is below.... https://teamtreehouse.com/library/build-a-social-network-with-flask/tacocat-challenge/the-challenge

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

import forms
import models

DEBUG = True
HOST = '0.0.0.0'
PORT = 8000

app=Flask(__name__)
app.secret_key='youdontknowmysecretkey'

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()
    g.user=current_user

@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(
          email=form.email.data,
          password=form.password.data
      )
        return redirect(url_for('index'))
    return render_template('register.html', form=form)

@app.route('/')
def index():
    try:
        tacos=models.Taco.select()
    except models.DoesNotExist:    
        return render_template('índex.html')
    else:
        return render_template('index.html', tacos=tacos)

@app.route('/login', methods=('GET', 'POST'))
def login():
    form=forms.LoginForm()
    if form.validate_on_submit():
    try:
        user = models.User.get(models.User.email==form.email.data)
    except models.DoesNotExist:
        flash("Email is incompatible", "error")
    else:
        if check_password_hash(user.password, form.password.data):
            login_user(user)
            flash("You are logged in", "success")
            return redirect(url_for('index'))
        else:
            flash("Password does not match", "error")
    return render_template('login.html', form=form)

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

#@app.route('/taco', methods=('GET','POST'))
@app.route('/taco', methods=['POST'])
@login_required
def taco():
    form = forms.CreateTacoForm()
    if form.validate_on_submit():
        flash("You Successfully Created Your Taco", "success")
        models.Taco.create_taco(user=g.user._get_current_object(),
                           protein=form.protein.data,
                           shell=form.shell.data,
                           cheese=form.cheese.data,
                           extras=form.extras.data.strip()
                          )
        return redirect(url_for('index'))
    return render_template('taco.html', form=form)


#@app.route('/')
#def index():
   # tacos = models.Taco.select().limit(10)
    #return render_template('index.html', tacos=tacos)




if __name__== '__main__':
    models.initialize()
     try:
    #with models.DATABASE.transaction():
        models.User.create_user(
          email = 'billy@example.com',
          password = 'password'
        )
    except ValueError:
    pass
models.py
import datetime

from flask.ext.bcrypt import Bcrypt, generate_password_hash, check_password_hash
from flask.ext.login import UserMixin
from peewee import *

DATABASE = SqliteDatabase('taco.db')

class User(UserMixin, Model):
    email=CharField(unique=True)
    password=CharField(max_length=100)

    class meta:
         database=DATABASE

    #def get_tacos(self):
        #return Taco.select().where(Taco.user == self)

    #def get_stream(self):
       # return Taco.select().where(
         # (Taco.user == self)
      #)

    @classmethod
    def create_user(cls, email, password):
         try:
                with DATABASE.transaction():
            cls.create(
                email=email,
                password=generate_password_hash(password))
        except IntegrityError:
            raise ValueError("User already exists")

class Taco(Model):
    protein=CharField()
    shell=CharField()
    cheese=BooleanField(default=True)
    extras=TextField()
    user=ForeignKeyField(
        rel_model=User,
        related_name='tacos'
    )

    class meta:
        database = DATABASE

@classmethod
    def create_taco(cls, protein, shell, cheese, extras, user):
        with DATABASE.transaction():#this is something I had in my notes
            cls.create(
                protein=protein,
                shell=shell,
                cheese=cheese,
                extras=extras,
                user=user)

def initialize():
    DATABASE.connect()
    DATABASE.create_tables([User, Taco], safe=True)
    DATABASE.close()
forms.py
from flask_wtf import Form
from wtforms import StringField, PasswordField, BooleanField, TextField
from wtforms.validators import DataRequired, ValidationError, Email,
                               Length, EqualTo, Regexp

from models import User

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

class RegisterForm(Form):
    email=StringField(
        'Email',
        validators=[
            DataRequired(),
            Email(),
            email_exists,
      ])
    password=PasswordField(
        'Password',
        validators=[
            DataRequired(),
            Length(min=2),
            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()])

class TacoForm(Form):
    protein=StringField('Protein', validators = [DataRequired()])
    shell =StringField('Shell', validators = [DataRequired()])
    cheese = BooleanField('Cheese')
    extras = TextAreaField("Any extras?")
templates/layout.html
<!doctype html>
<html>
  <head>
    <title>Tacocat</title>
    <link rel="stylesheet" href="/static/css/normalize.css">
    <link rel="stylesheet" href="/static/css/skeleton.css">
    <link rel="stylesheet" href="/static/css/tacocat.css">
  </head>
  <body>
    {% with messages=get_flashed_messages() %}
    {% if messages %}
        <div class="messages">
          {% for message in messages %}
          <div class="message">
            {{ message }}
          </div>
          {% endfor %}
        </div>
      {% endif %}
    {% endwith %}

    <div class="container">
      <div class="row">
        <div class="u-full-width">
          <nav class="menu">
            <!-- menu goes here -->
              {% if current_user.is_authenticated() %}
                <a href="{{ url_for('logout') }}" title="Log Out">Logout</a>
                <a href="{{ url_for('taco') }}" title="New Taco">Add a New Taco</a>
              {% else %}
                <a href="{{ url_for('login') }}" title ="Log in">Login</a>
                <a href="{{ url_for('register') }}" title="Sign Up">Sign Up</a>
              {% endif %}
          </nav>
          {% block content %}{% endblock %}
        </div>
      </div>
      <footer>
        <p>An MVP web app made with Flask on <a href="http://teamtreehouse.com">Treehouse</a>.</p>
      </footer>
    </div>
  </body>
</html>
templates/index.html
{% extends 'layout.html' %}

{% block content %}
<h2>Tacos</h2>
    {% if tacos.count() %}
        <table class="u-full-width">
          <thead>
            <tr>
              <th>Protein</th>
              <th>Cheese?</th>
              <th>Shell</th>
              <th>Extras</th>
            </tr>
          </thead>
          <tbody>
        {% for taco in tacos %}
           <tr>
              <!-- taco attributes here -->
              <th>{{taco.protein}}</th>
              <th>{{taco.cheese}}</th>
              <th>{{taco.shell}}</th>
              <th>{{taco.extras}}</th>
            </tr>
        {% endfor %}
          </tbody>
        </table>
    {% else %}
        <!-- message for missing tacos -->
        <h2>No Tacos Yet</h2>
    {% endif %}
{% endblock %}

3 Answers

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,722 Points

It is great you are sharing your code! This is a good way to show your thought process and work.

Tacocat is one of the most demanding Code Challenges at Treehouse. The way to really do it properly would be to develop the code in a stand-alone workspace as you would have the best opportunity to debug errors coming from the code. Since you will see both syntax errors attempting to run the code and runtime errors that will happen as you login and render the templates.

And there are, indeed, a bunch of errors that need to be fixed--

To save time, I did a snapshot of a working version of tacocat you can refer to this for exact syntax. Note that this is a partial solution to the project, but the code will bootstrap your approach to solving the Challenge.

Good luck with your Python studies!

https://w.trhou.se/swxgoa4vx3

Error 0: In models.py places where you have class meta: you needed class Meta:

class User(UserMixin, Model):
    email=CharField(unique=True)
    password=CharField(max_length=100)

    class Meta:
         database=DATABASE

Error 1: For long import lines, ALWAYS use parenthesis to encapsulate all the imported functions

Here is the error it caused. File "/home/treehouse/workspace/tacocat.py", line 3
from flask.ext.login import LoginManager, login_user,
^
SyntaxError: trailing comma not allowed without surrounding parentheses

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

Error 2: File "/home/treehouse/workspace/tacocat.py", line 37
g.db.close
^
IndentationError: unindent does not match any outer indentation level

It should look like this--

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

Error 4: File "/home/treehouse/workspace/tacocat.py", line 45
models.User.create_user(
IndentationError: unexpected indent

It should be this--

@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(
          email=form.email.data,
          password=form.password.data
        )
        return redirect(url_for('index'))
    return render_template('register.html', form=form)

Error 5: File "/home/treehouse/workspace/tacocat.py", line 65
try:
^
IndentationError: expected an indented block

To avoid logical errors-- It should look like this:

@app.route('/login', methods=('GET', 'POST'))
def login():
    form=forms.LoginForm()
    if form.validate_on_submit():
        try:
            user = models.User.get(models.User.email==form.email.data)
        except models.DoesNotExist:
            flash("Email is incompatible", "error")

        if check_password_hash(user.password, form.password.data):
            login_user(user)
            flash("You are logged in", "success")
            return redirect(url_for('index'))
        else:
            flash("Password does not match", "error")

    return render_template('login.html', form=form)

Error 6: import error File "/home/treehouse/workspace/forms.py", line 3
from wtforms.validators import DataRequired, ValidationError, Email,
^
SyntaxError: trailing comma not allowed without surrounding parentheses

from wtforms.validators import (DataRequired, ValidationError,
                               Length, EqualTo, Regexp)

Error 7 and Error 8: File "/home/treehouse/workspace/models.py", line 28
cls.create(
^
IndentationError: unindent does not match any outer indentation level

File "/home/treehouse/workspace/models.py", line 32
except IntegrityError:
^
IndentationError: unindent does not match any outer indentation level

class User(UserMixin, Model):
    email=CharField(unique=True)
    password=CharField(max_length=100)

    class Meta:
         database=DATABASE

    @classmethod
    def create_user(cls, email, password):
        try:
            with DATABASE.transaction():
                cls.create(
                    email=email,
                    password=generate_password_hash(password)
                )
        except IntegrityError:
            raise ValueError("User already exists")

Error 9: File "/home/treehouse/workspace/models.py", line 49
def create_taco(cls, protein, shell, cheese, extras, user):
IndentationError: unexpected indent

class Taco(Model):
    protein=CharField()
    shell=CharField()
    cheese=BooleanField(default=True)
    extras=TextField()
    user=ForeignKeyField(
        rel_model=User,
        related_name='tacos'
    )

    class Meta:
        database = DATABASE

    @classmethod
    def create_taco(cls, protein, shell, cheese, extras, user):
        with DATABASE.transaction():#this is something I had in my notes
            cls.create(
                protein=protein,
                shell=shell,
                cheese=cheese,
                extras=extras,
                user=user)

Error 10: Remove references to the Email validators. This extra part of the forms package is not installed in the Challenge environment.

In your own development environment I expect it would be different.

Error 11: TextAreaField should be TextField

File "/home/treehouse/workspace/forms.py", line 38, in TacoForm
extras = TextAreaField("Any extras?")
NameError: name 'TextAreaField' is not defined

Error 12: Logical Error by the class when an error keeps user var from being instantiated. File "/home/treehouse/workspace/tacocat.py", line 70, in login if check_password_hash(user.password, form.password.data): UnboundLocalError: local variable 'user' referenced before assignment

thank you this is indeed a tough challenge

if you don't mind can you give me you full codes i keep getting it wrong

Jeff Muday
Jeff Muday
Treehouse Moderator 28,722 Points

The full code is linked below, but YOU must comment out the "app.run(host=HOST, port=PORT, debug=True)" statement.

Use the link to see the snapshot of the code.

https://w.trhou.se/swxgoa4vx3