Errata

Flask Web Development

Errata for Flask Web Development

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
ePub
Page Chapter 6
Table 6.1

The table states that MAIL_HOSTNAME is the key to use for setting the mail server. However, the correct key is MAIL_SERVER, as in the example code.

Note from the Author or Editor:
I have updated the manuscript with this correction for future editions.

Anonymous  Jun 04, 2014  Dec 05, 2014
PDF
Page xiii
at the bottom of the Viewing All Changes in a Revision section

The URL spans 2 lines and there is an extra dash in it, due to the line break, but that makes the URL not work!

can be viewed on GitHub by typing URL https://github.com/miguelgrin-
berg/flasky/compare/2a?2b in your web browser.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Anonymous  Feb 13, 2014  Apr 25, 2014
ePub
Page chapter 6
United States

In the text below, you would have to import app from hello.py for the code to work.


Sending Emails from the Python Shell

To test the configuration you can start a shell session and send a test email:
> > > from flask.ext.mail import Message
> > > from hello import mail
> > > msg = Message('test subject', sender ='you@example.com', ...
recipients =['you@example.com'])
> > > msg.body = 'text body'
> > > msg.html = '< b > HTML </ b > body'
> > > with app.app_context():
... mail.send( msg)

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Sean Murphy  Feb 26, 2014  Apr 25, 2014
ePub
Page Chapter 7
United States

Example 7-4. app/main/_)init___.py: Blueprint creation.

file name above should be __init__.py

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Sean Murphy  Feb 27, 2014  Apr 25, 2014
ePub
Page 8-12
United States

There is an extra {% endblock %} in the example 8-12 template for login. This extra endblock is not in the git repo for the book but is shown in the book text.

{% extends "base.html" %}
{% import "bootstrap/ wtf.html" as wtf %}

{% block title %} Flasky - Login{% endblock %}

{% block page_content %}
<div class="page-header">
<h1>Login</h1>
</div>
{% endblock %}

<div class="col-md-4">
{{ wtf.quick_form( form) }}
</div>
{% endblock %}

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Sean Murphy  Mar 02, 2014  Apr 25, 2014
ePub
Page 8
The line says $git reset -hard

The line should say $ git reset --hard (please note the double dashes)

Actually I just changed my font in Google Play to Sans and see it is displayed correctly. You may want to suggest users display the book in Sans Serif.

Great book so far

Note from the Author or Editor:
This is has been changed to code font, so it looks much better now. Note that this report applies to the early release of the book.

Michael Brennan-White  Mar 09, 2014  Apr 25, 2014
PDF
Page 13
raven-paragraph about threading

A thread is the smallest sequence of instructions that can be managed independently. It is common for a process to have multiple active threads, sometimes sharing resources such as memory or file handles. **Multi-threaded web browsers** start a pool of threads and select a thread from the pool to handle each incoming request.

Per context, "Multi-threaded web browsers" should be "Multi-threaded web servers" instead.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Anonymous  Mar 10, 2014  Apr 25, 2014
PDF
Page 16
United States

The get_user(id) function on page 16 calls itself, leading to a RuntimeError exception.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Edward Kozlowski  Mar 03, 2014  Apr 25, 2014
PDF
Page 22
Example 3.3

In Example 3.3: It is

@app.route('/index')
def index():
...

It should be:

@app.route('/')
def index():
...

In the same example from github it's correct.

Note from the Author or Editor:
I have corrected the manuscript for future editions.

Farhad Fouladi  Aug 27, 2014  Dec 05, 2014
PDF
Page 39
Under "Form Handling in View Function" heading.

The example (4.4) appears to indicate the updated index function will be in hello.py. Will it not remain in routes.py? There is a similar instance on page 43 (Example 4.5)

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Greg Lindstrom  Feb 07, 2014  Apr 25, 2014
PDF
Page 40
Section "HTML Rendering of Forms"

The first two code examples in this section show how to render a form in a template, but are incomplete as they do not show how to implement CSRF protection, which requires a hidden form field that holds a CSRF token. This can be added by adding {{ form.hidden_tag() }} inside the form.

Miguel Grinberg
Miguel Grinberg
 
May 31, 2014  Dec 05, 2014
PDF, ePub, Mobi,
Page 41
3rd paragraph

"Conditionals in Jinja2 have the format {% if variable %}...{% else %}...{% endif %}."

The "if variable" in Jinja2 template representation should be reformulated to "if condition". The rest of the text is alright and tells exactly what it is. The condition may be a variable but it is not necessarily one.

Thank you for the book.

Note from the Author or Editor:
I have fixed this mistake in Atlas for future editions.

Marco Agner  Jul 20, 2014  Dec 05, 2014
PDF
Page 46
Example 4-6

The line that reads form.name.data = '' does not have any effect, it was left there by mistake.

Miguel Grinberg
Miguel Grinberg
 
May 31, 2014  Dec 05, 2014
PDF
Page 60
Ch 4, section "HTML Rendering of Forms", first para

The paragraph begins: "Form fields are callables that, when invoked, from a template render themselves ..." Should the second comma appear after "template" rather than after "invoked"?

Note from the Author or Editor:
Yes, that comma is in the wrong place. I have made the correction in the book source files.

Ken Hommel  Jun 17, 2014  Dec 05, 2014
PDF
Page 62
Example 5-4. app/models.py: Dynamic relationships

Up until page 62, there has been no mention of models.py. All the code was being entered into hello.py and the other template files. So someone who is typing along rather that checking out the code from the repo, will at that moment have typed the code that creates the models and its related imports in the hello.py module.

Then suddenly on page 62 we you have:

Example 5-4. app/models.py: Dynamic relationships
class Role(db.Model):
# ...
users = db.relationship('User', backref='role', lazy='dynamic')
# ...

This threw me off. I had to reorganise my code and move the related code into the models.py. Please fix this because for a complete novice, it could be a major source of confusion. Thanks anyway for a very fantastic book. I've not written a review yet but I hope to do soon.

Note from the Author or Editor:
I have corrected this in the book source files for future releases.

Napoleon  Jun 18, 2014  Dec 05, 2014
PDF, ePub
Page 62
Example 5-7

Using the code in the book and on git:

>>> app
<Flask 'app'>

Should show instead:
>>> app
<Flask 'hello'>

And:

>>> User
<class 'app.User'>

Should show:
>>> User
<class '__main__.User'>

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Antonio Manuel Mac?as Ojeda  Mar 04, 2014  Apr 25, 2014
ePub
Page 67
end of page

The instructions state to type python manage.py shell when the call should be to hello.py

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Michael Brennan-White  Mar 10, 2014  Apr 25, 2014
PDF
Page 68
First paragraph after code

The text reads, "The recipient of the email is given in the FLASK_ADMIN environment variable..." but FLASK_ADMIN should be FLASKY_ADMIN as it is in the code.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Anonymous  Apr 20, 2014  Apr 25, 2014
ePub
Page 72
Heading of Example 7.4

path to file for Example 7.4 should be app/main/init.py instead of app/init.py. At least when I compare to source code on github.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Dan  Jan 31, 2014  Apr 25, 2014
PDF
Page 72
4th code sample

p58 of text, p72 of PDF

~~~~~
>>> str(User.query.filter_by(name='User'))
'SELECT users.id AS users_id, users.username AS users_username,
users.role_id AS users_role_id FROM users WHERE :param_1 = users.role_id'
~~~~~

and

~~~~~
>>> user_role = Role.query.filter_by(name = 'User').first()
~~~~~

`name` should be `username`

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Brian Wisti  Feb 15, 2014  Apr 25, 2014
PDF
Page 77
4th paragraph (last)

"Configuration classes can define a init_app() class method that takes an application instance as an argument. Here configuration-specific initialization can performed."

Should read:

"Configuration classes can define a init_app() class method that takes an application instance as an argument. Here configuration-specific initialization can BE performed."

Thank you for the great book.

Note from the Author or Editor:
I have made a correction in the manuscript for future editions.

Marco Agner  Jul 27, 2014  Dec 05, 2014
PDF
Page 77
5th para.

Here configuration-specific initialization can performed -> Here configuration-specific initialization can be performed

Ron Barak  Nov 27, 2016 
PDF
Page 80
Example 7-5

The line that imports the blueprint is missing a dot. The correct statement is: from .main import main as main_blueprint (note the dot before "main").

Miguel Grinberg
Miguel Grinberg
 
May 31, 2014  Dec 05, 2014
PDF
Page 82
PDF pg 62, Example 5-5

The Python formatting in this source code is inconsistent about the format for assigning values to named parameters. When assigning values to named parameters in a function call there should be no spaces around the assignment operator ('='). This is used correctly at some points ("User.query.filter_by(username=form.name.data).first()) but not in others ("User(username = form.name.data)").

In particular, note the call to render_template().

Minor issue, just looking for consistency.

Note from the Author or Editor:
Made a correction in Atlas.

Ken Hommel  Jun 19, 2014  Dec 05, 2014
PDF
Page 88
First bullet point after second paragraph

Currently reads:

This function takes a plan text password and returns the password hash and the random salt used, both combined into a single string that can be stored in the user database.

Should read:

This function takes a plain text password and returns the password hash and the random salt used, both combined into a single string that can be stored in the user database.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Andrew Jackson  Mar 08, 2014  Apr 25, 2014
PDF
Page 88
Following using code breakout box

breakout box currently reads:

If you have cloned the application?s git repository on GitHub you can run git checkout 8c to checkout this version of the application. This update contains a database migration, remember to run python manage.py db upgrade after you checkout the code. To ensure that you have all the dependencies installed also run pip -r requirements.txt.

Breakout box should read:

If you have cloned the application?s git repository on GitHub you can run git checkout 8c to checkout this version of the application. This update contains a database migration, remember to run python manage.py db upgrade after you checkout the code. To ensure that you have all the dependencies installed also run pip install -r requirements.txt.

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Andrew Jackson  Mar 08, 2014  Apr 25, 2014
PDF
Page 95
6th para.

In Example 8-8, there should also be a mention how user_id is created and manipulated.

Note from the Author or Editor:
incorporated in the 2nd edition manuscript.

Ron Barak  Nov 27, 2016 
Printed
Page 96
Example 8-10

In Example 8-10 it is written "Sign Out" and "Sign In". In the corresponding Figure 8-1 the word "Log In" is displayed. Either the Example or the Figure should be changed.

In file "app/templates/base.html" in "flasky" git repository the words "Log Out" and "Log In" are implemented. IMHO, the Example 8-10 should be corrected.

Note from the Author or Editor:
I'm updating the manuscript in Atlas for future editions.

Farhad Fouladi  Jan 26, 2015 
PDF
Page 101
2nd para.

This form uses the Regexp validator from WTForms to ensure that the username field contains letters, numbers, underscores, and dots only. -> This form uses the Regexp validator from WTForms to ensure that the username field starts with a letter and contains letters, numbers, underscores, and dots only.

Ron Barak  Nov 27, 2016 
PDF
Page 106
5th para.

because the browser converts them to absolute by adding -> because the browser converts them to absolute URLs by adding

Note from the Author or Editor:
2nd edition manuscript updated with this suggestion

Ron Barak  Nov 27, 2016 
PDF
Page 108
Example 8-23. app/auth/views.py: Resend account confirmation email

@auth.route('/confirm')
@login_required
def resend_confirmation():
token = current_user.generate_confirmation_token()
send_email('auth/email/confirm', 'Confirm Your Account', user, token=token)
flash('A new confirmation email has been sent to you by email.')
return redirect(url_for('main.index'))

===>

@auth.route('/confirm')
@login_required
def resend_confirmation():
token = current_user.generate_confirmation_token()
send_email(current_user.email, 'Confirm Your Account', 'auth/email/confirm', user=current_user, token=token)
flash('A new confirmation email has been sent to you by email.')
return redirect(url_for('main.index'))

Note from the Author or Editor:
The send_email() call in this example uses an incorrect argument list.

Wang Yandong  May 29, 2014  Dec 05, 2014
PDF
Page 116
PDF pg 96, Ch 8, Adding a Login Form, Example 8-9

The imports should include "Length" from wtforms.validators.

Note from the Author or Editor:
Made a correction in Atlas.

Ken Hommel  Jun 23, 2014  Dec 05, 2014
PDF
Page 119
Example 10-5

~~~~~
Last seen {{ moment(user.member_since).fromNow() }}.
~~~~~

Should be

~~~~~
Last seen {{ moment(user.last_seen).fromNow() }}.
~~~~~

Note from the Author or Editor:
This report applies to the early release of the book. I have already made a correction in the manuscript.

Brian Wisti  Feb 25, 2014  Apr 25, 2014
Printed
Page 133
After <div class="profile-thumbnail">...</div>

div elements after the thumbnail div should be wrapped in

<div class="post-content">
...
</div>

to properly space author link and body from thumbnail.

This is reflected in the github code, but not in print.

Thanks!

Note from the Author or Editor:
Incorporated towards 2nd edition of the book.

Aaron Nichols  Jun 17, 2017 
PDF
Page 165
First sentence of the final paragraph.

The sentence reads as,

Comments apply specific blog posts, so a one-to-many..

When I think the author is intending to say:

Comments apply <em>to</em> specific blog posts, so a one-to-many...

Note from the Author or Editor:
I have updated the book source files for a future edition.

Anonymous  Aug 30, 2015 
Printed
Page 181
Example 14-5

Directory for location of errors.py file indicated as "app/api/errors.py" which should be "app/api_1_0/errors.py"

Note from the Author or Editor:
Addressed in the 2nd edition manuscript.

Matt Dublin  Dec 29, 2016 
PDF
Page 184
In 'Token-Based Authentication'

In the definition of User.generate_auth_token, according to the text, it is set to return 's.dumps({'id': self.id})' which will cause the tests mentioned in 15c to fail.

The GitHub page correctly has the function return 's.dumps({'id': self.id}).decode('ascii')'

Note from the Author or Editor:
I have corrected the book source files for the next reprint.

Anonymous  Sep 07, 2015 
Printed
Page 184
top of page, end of 14-8 example function started on previous page

Shouldn't the before_request() function be:

return forbidden_error('Unconfirmed account')

instead of:

return forbidden('Unconfirmed account')

?

Note from the Author or Editor:
Correction added to the 2nd edition of the book manuscript.

Matt Dublin  Dec 29, 2016 
PDF
Page 191
Second row of table

In table 14-3 in the second row on page 191, the Resource URL for comments on a blog post is written as

/posts/<int:id/>comments/

When it should be

/posts/<int:id>/comments/

It is correct on GitHub.

Note from the Author or Editor:
Book source files updated.

Anonymous  Sep 02, 2015 
PDF
Page 204-205
inside the test_posts function

The test_posts function has two minor errors.

First, it uses "self.get_auth_header" for it's header under '# write a post' when it should be "self.get_api_headers" as it is in GitHub.

Second, in that same section, the value of the data diction is written as 'body of the blog post' when in the assertion check below, the body json_response is defined as 'body of the *blog* post' and the body_html response is defined as '<p>body of the <em>blog</em> post</p>'.

The original definition of the body value in the data dictionary should be "body of the *blog* post" to reflect the assertions.

Note from the Author or Editor:
Book source files updated.

Anonymous  Sep 03, 2015 
PDF
Page 209
South Africa

Selenium version in requirements.txt

Hello

The version of Selenium included in the requirements.txt file fails to execute the tests. Further inspection showed that it fails to a an error: "Failed to load profile".

This is fixed in later versions of Selenium so upgrading Selenium (pip install -U selenium) resolved the problem.

Thanks for a great book.

Jaco


Note from the Author or Editor:
I will review this problem and update the requirements.

Jaco Smuts  Nov 03, 2014  Dec 05, 2014