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 trialGinny Pennekamp
31,466 PointsWhy am I getting a Key Error when I run app_tests.py?
Traceback (most recent call last):
File "app_tests.py", line 6, in <module>
import tacocat
File "/Users/Ginny/Desktop/Websites/Flask projects/TacoCat/tacocat.py", line 8, in <module>
import forms
File "/Users/Ginny/Desktop/Websites/Flask projects/TacoCat/forms.py", line 6, in <module>
from models import User
File "/Users/Ginny/Desktop/Websites/Flask projects/TacoCat/models.py", line 35, in <module>
class Taco(Model):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/peewee.py", line 4072, in __new__
cls._meta.prepared()
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/peewee.py", line 3911, in prepared
field = self.fields[item.lstrip('-')]
KeyError: ''
import datetime
from flask.ext.bcrypt import generate_password_hash
from flask.ext.login import UserMixin
from peewee import *
DATABASE = SqliteDatabase('tacocat.db')
class User(UserMixin, Model):
"""A taco cat customer"""
username = CharField(unique=True)
email = CharField(unique=True)
password = CharField(max_length=100)
is_admin = BooleanField(default=False)
class Meta:
database = DATABASE
@classmethod
def create_user(cls, username, email, password, admin=False):
try:
with DATABASE.transaction():
cls.create(
username=username,
email=email,
password=generate_password_hash(password),
is_admin=admin)
except IntegrityError:
raise ValueError("User already exists")
class Taco(Model):
"""Taco creation by the customer"""
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model=User,
related_name='tacos'
)
protein = CharField(max_length=100)
cheese = BooleanField()
shell = CharField(max_length=100)
extras = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp')
def initialize():
DATABASE.connect()
DATABASE.create_tables([User, Taco], safe=True)
DATABASE.close()
import datetime
from flask.ext.bcrypt import generate_password_hash
from flask.ext.login import UserMixin
from peewee import *
DATABASE = SqliteDatabase('tacocat.db')
class User(UserMixin, Model):
"""A taco cat customer"""
username = CharField(unique=True)
email = CharField(unique=True)
password = CharField(max_length=100)
is_admin = BooleanField(default=False)
class Meta:
database = DATABASE
@classmethod
def create_user(cls, username, email, password, admin=False):
try:
with DATABASE.transaction():
cls.create(
username=username,
email=email,
password=generate_password_hash(password),
is_admin=admin)
except IntegrityError:
raise ValueError("User already exists")
class Taco(Model):
"""Taco creation by the customer"""
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model=User,
related_name='tacos'
)
protein = CharField(max_length=100)
cheese = BooleanField()
shell = CharField(max_length=100)
extras = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp')
def initialize():
DATABASE.connect()
DATABASE.create_tables([User, Taco], safe=True)
DATABASE.close()
from flask_wtf import Form
from wtforms import StringField, PasswordField, TextAreaField, BooleanField
from wtforms.validators import (DataRequired, Regexp, ValidationError, Email,
Length, EqualTo)
from models import User
def name_exists(form, field):
"""Register fails because it is a username that already exists in the database"""
if User.select().where(User.username == field.data).exists():
raise ValidationError('User with that name already exists.')
def email_exists(form, field):
"""Register fails because it is an email that already exists in the database"""
if User.select().where(User.email == field.data).exists():
raise ValidationError('User with that email already exists.')
class RegisterForm(Form):
"""Creates a form to register a new user"""
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=2),
EqualTo('password2', message='Passwords must match')
])
password2 = PasswordField(
'ConfirmPassword',
validators=[DataRequired()]
)
class LoginForm(Form):
"""Creates a form to log a user in"""
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
class TacoForm(Form):
"""Creates a form to order a taco"""
protein = StringField("Meat? Chicken? Pork? Veggie?", validator=[DataRequired()])
cheese = BooleanField("Cheese", default=True)
shell = StringField("Corn? Wheat? Crispy? Soft?", validator=[DataRequired()])
extras = TextAreaField("Anything else?", validator=[DataRequired()])
<!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 -->
<a href="{{ url_for('register') }}">Sign Up</a>
<a href="{{ url_for('login') }}">Sign In</a>
{% if current_user.is_authenticated() %}
<a href="{{ url_for('create_taco') }}">Create a Tacop</a>
<a href="{{ url_for('logout') }}">Sign Out</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>
{% 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 -->
<td>{{ taco.protein }}</td>
<td>{{ taco.cheese }}</td>
<td>{{ taco.shell }}</td>
<td>{{ taco.extras }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<!-- message for missing tacos -->
<h5>No tacos yet!</h5>
{% endif %}
{% endblock %}
[edit formating -cf]
1 Answer
Chris Freeman
Treehouse Moderator 68,454 PointsI looks like the order_by
is incorrect. Try ordering
:
class Taco(Model):
"""Taco creation by the customer"""
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model=User,
related_name='tacos'
)
protein = CharField(max_length=100)
cheese = BooleanField()
shell = CharField(max_length=100)
extras = TextField()
class Meta:
database = DATABASE
# Not correct (unless using Django)
# ordering = ('-timestamp') #<-- changed to "ordering"
# corrected answer
order_by = ('-timestamp',) #<-- Adding a comma make a tuple
[Edit: updated answer for peewee (not Django). Doh!]
Ginny Pennekamp
31,466 PointsGinny Pennekamp
31,466 PointsHi Chris,
Thanks so much for your help -- changing "order_by" to "ordering" did get rid of my KeyError.
Quick Question though: in the workspaces for our Social Media App, the wording for this code was "order_by" -- why the change here?
Chris Freeman
Treehouse Moderator 68,454 PointsChris Freeman
Treehouse Moderator 68,454 PointsRight! The actual solution is closer to your original code: Add a comma to make it a tuple! Without the comma it's just a string and
order_by
expects a list or a tuple. So try:I've changed my answer above to reflect this change. My previous answer using
ordering
was based on Django, not peewee. Oops!Ginny Pennekamp
31,466 PointsGinny Pennekamp
31,466 PointsRIGHT! I now remember Kenneth making a big deal out of the tuple in the video. Doh!
Ordering worked in the short term, though, and got me past that error so that I could at least run the tests and pass the challenge, so thank you again for that.