<h1>Blueprints and Views<aclass="headerlink"href="#blueprints-and-views"title="Link to this heading">¶</a></h1>
<p>A view function is the code you write to respond to requests to your
application. Flask uses patterns to match the incoming request URL to
the view that should handle it. The view returns data that Flask turns
into an outgoing response. Flask can also go the other direction and
generate a URL to a view based on its name and arguments.</p>
<sectionid="create-a-blueprint">
<h2>Create a Blueprint<aclass="headerlink"href="#create-a-blueprint"title="Link to this heading">¶</a></h2>
<p>A <aclass="reference internal"href="../api.html#flask.Blueprint"title="flask.Blueprint"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">Blueprint</span></code></a> is a way to organize a group of related views and
other code. Rather than registering views and other code directly with
an application, they are registered with a blueprint. Then the blueprint
is registered with the application when it is available in the factory
function.</p>
<p>Flaskr will have two blueprints, one for authentication functions and
one for the blog posts functions. The code for each blueprint will go
in a separate module. Since the blog needs to know about authentication,
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id1"title="Link to this code">¶</a></div>
<p>This creates a <aclass="reference internal"href="../api.html#flask.Blueprint"title="flask.Blueprint"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">Blueprint</span></code></a> named <codeclass="docutils literal notranslate"><spanclass="pre">'auth'</span></code>. Like the application
object, the blueprint needs to know where it’s defined, so <codeclass="docutils literal notranslate"><spanclass="pre">__name__</span></code>
is passed as the second argument. The <codeclass="docutils literal notranslate"><spanclass="pre">url_prefix</span></code> will be prepended
to all the URLs associated with the blueprint.</p>
<p>Import and register the blueprint from the factory using
<aclass="reference internal"href="../api.html#flask.Flask.register_blueprint"title="flask.Flask.register_blueprint"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">app.register_blueprint()</span></code></a>. Place the
new code at the end of the factory function before returning the app.</p>
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/__init__.py</span></code></span><aclass="headerlink"href="#id2"title="Link to this code">¶</a></div>
<p>The authentication blueprint will have views to register new users and
to log in and log out.</p>
</section>
<sectionid="the-first-view-register">
<h2>The First View: Register<aclass="headerlink"href="#the-first-view-register"title="Link to this heading">¶</a></h2>
<p>When the user visits the <codeclass="docutils literal notranslate"><spanclass="pre">/auth/register</span></code> URL, the <codeclass="docutils literal notranslate"><spanclass="pre">register</span></code> view
will return <aclass="reference external"href="https://developer.mozilla.org/docs/Web/HTML">HTML</a> with a form for them to fill out. When they submit
the form, it will validate their input and either show the form again
with an error message or create the new user and go to the login page.</p>
<p>For now you will just write the view code. On the next page, you’ll
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id3"title="Link to this code">¶</a></div>
<spanclass="n">error</span><spanclass="o">=</span><spanclass="sa">f</span><spanclass="s2">"User </span><spanclass="si">{</span><spanclass="n">username</span><spanclass="si">}</span><spanclass="s2"> is already registered."</span>
with the <codeclass="docutils literal notranslate"><spanclass="pre">register</span></code> view function. When Flask receives a request
to <codeclass="docutils literal notranslate"><spanclass="pre">/auth/register</span></code>, it will call the <codeclass="docutils literal notranslate"><spanclass="pre">register</span></code> view and use
the return value as the response.</p></li>
<li><p>If the user submitted the form,
<aclass="reference internal"href="../api.html#flask.Request.method"title="flask.Request.method"><codeclass="xref py py-attr docutils literal notranslate"><spanclass="pre">request.method</span></code></a> will be <codeclass="docutils literal notranslate"><spanclass="pre">'POST'</span></code>. In this
case, start validating the input.</p></li>
<li><p><aclass="reference internal"href="../api.html#flask.Request.form"title="flask.Request.form"><codeclass="xref py py-attr docutils literal notranslate"><spanclass="pre">request.form</span></code></a> is a special type of
<aclass="reference external"href="https://docs.python.org/3/library/stdtypes.html#dict"title="(in Python v3.13)"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">dict</span></code></a> mapping submitted form keys and values. The user will
input their <codeclass="docutils literal notranslate"><spanclass="pre">username</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">password</span></code>.</p></li>
<li><p>Validate that <codeclass="docutils literal notranslate"><spanclass="pre">username</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">password</span></code> are not empty.</p></li>
<li><p>If validation succeeds, insert the new user data into the database.</p>
query with <codeclass="docutils literal notranslate"><spanclass="pre">?</span></code> placeholders for any user input, and a tuple of
values to replace the placeholders with. The database library
will take care of escaping the values so you are not vulnerable
to a <em>SQL injection attack</em>.</p></li>
<li><p>For security, passwords should never be stored in the database
directly. Instead,
<aclass="reference external"href="https://werkzeug.palletsprojects.com/en/stable/utils/#werkzeug.security.generate_password_hash"title="(in Werkzeug v3.1.x)"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">generate_password_hash()</span></code></a> is used to
securely hash the password, and that hash is stored. Since this
query modifies data,
<aclass="reference external"href="https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.commit"title="(in Python v3.13)"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">db.commit()</span></code></a> needs to be
called afterwards to save the changes.</p></li>
<li><p>An <aclass="reference external"href="https://docs.python.org/3/library/sqlite3.html#sqlite3.IntegrityError"title="(in Python v3.13)"><codeclass="xref py py-exc docutils literal notranslate"><spanclass="pre">sqlite3.IntegrityError</span></code></a> will occur if the username
already exists, which should be shown to the user as another
validation error.</p></li>
</ul>
</li>
<li><p>After storing the user, they are redirected to the login page.
<aclass="reference internal"href="../api.html#flask.url_for"title="flask.url_for"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">url_for()</span></code></a> generates the URL for the login view based on its
name. This is preferable to writing the URL directly as it allows
you to change the URL later without changing all code that links to
it. <aclass="reference internal"href="../api.html#flask.redirect"title="flask.redirect"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">redirect()</span></code></a> generates a redirect response to the generated
URL.</p></li>
<li><p>If validation fails, the error is shown to the user. <aclass="reference internal"href="../api.html#flask.flash"title="flask.flash"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">flash()</span></code></a>
stores messages that can be retrieved when rendering the template.</p></li>
<li><p>When the user initially navigates to <codeclass="docutils literal notranslate"><spanclass="pre">auth/register</span></code>, or
there was a validation error, an HTML page with the registration
form should be shown. <aclass="reference internal"href="../api.html#flask.render_template"title="flask.render_template"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">render_template()</span></code></a> will render a template
containing the HTML, which you’ll write in the next step of the
tutorial.</p></li>
</ol>
</section>
<sectionid="login">
<h2>Login<aclass="headerlink"href="#login"title="Link to this heading">¶</a></h2>
<p>This view follows the same pattern as the <codeclass="docutils literal notranslate"><spanclass="pre">register</span></code> view above.</p>
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id4"title="Link to this code">¶</a></div>
<spanclass="s1">'SELECT * FROM user WHERE username = ?'</span><spanclass="p">,</span><spanclass="p">(</span><spanclass="n">username</span><spanclass="p">,)</span>
<p>There are a few differences from the <codeclass="docutils literal notranslate"><spanclass="pre">register</span></code> view:</p>
<olclass="arabic">
<li><p>The user is queried first and stored in a variable for later use.</p>
<p><aclass="reference external"href="https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.fetchone"title="(in Python v3.13)"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">fetchone()</span></code></a> returns one row from the query.
If the query returned no results, it returns <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code>. Later,
<aclass="reference external"href="https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.fetchall"title="(in Python v3.13)"><codeclass="xref py py-meth docutils literal notranslate"><spanclass="pre">fetchall()</span></code></a> will be used, which returns a list
password in the same way as the stored hash and securely compares
them. If they match, the password is valid.</p></li>
<li><p><aclass="reference internal"href="../api.html#flask.session"title="flask.session"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">session</span></code></a> is a <aclass="reference external"href="https://docs.python.org/3/library/stdtypes.html#dict"title="(in Python v3.13)"><codeclass="xref py py-class docutils literal notranslate"><spanclass="pre">dict</span></code></a> that stores data across requests.
When validation succeeds, the user’s <codeclass="docutils literal notranslate"><spanclass="pre">id</span></code> is stored in a new
session. The data is stored in a <em>cookie</em> that is sent to the
browser, and the browser then sends it back with subsequent requests.
Flask securely <em>signs</em> the data so that it can’t be tampered with.</p></li>
</ol>
<p>Now that the user’s <codeclass="docutils literal notranslate"><spanclass="pre">id</span></code> is stored in the <aclass="reference internal"href="../api.html#flask.session"title="flask.session"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">session</span></code></a>, it will be
available on subsequent requests. At the beginning of each request, if
a user is logged in their information should be loaded and made
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id5"title="Link to this code">¶</a></div>
<spanclass="s1">'SELECT * FROM user WHERE id = ?'</span><spanclass="p">,</span><spanclass="p">(</span><spanclass="n">user_id</span><spanclass="p">,)</span>
a function that runs before the view function, no matter what URL is
requested. <codeclass="docutils literal notranslate"><spanclass="pre">load_logged_in_user</span></code> checks if a user id is stored in the
<aclass="reference internal"href="../api.html#flask.session"title="flask.session"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">session</span></code></a> and gets that user’s data from the database, storing it
on <aclass="reference internal"href="../api.html#flask.g"title="flask.g"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">g.user</span></code></a>, which lasts for the length of the request. If
there is no user id, or if the id doesn’t exist, <codeclass="docutils literal notranslate"><spanclass="pre">g.user</span></code> will be
<h2>Logout<aclass="headerlink"href="#logout"title="Link to this heading">¶</a></h2>
<p>To log out, you need to remove the user id from the <aclass="reference internal"href="../api.html#flask.session"title="flask.session"><codeclass="xref py py-data docutils literal notranslate"><spanclass="pre">session</span></code></a>.
Then <codeclass="docutils literal notranslate"><spanclass="pre">load_logged_in_user</span></code> won’t load a user on subsequent requests.</p>
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id6"title="Link to this code">¶</a></div>
<divclass="code-block-caption"><spanclass="caption-text"><codeclass="docutils literal notranslate"><spanclass="pre">flaskr/auth.py</span></code></span><aclass="headerlink"href="#id7"title="Link to this code">¶</a></div>
<p>This decorator returns a new view function that wraps the original view
it’s applied to. The new function checks if a user is loaded and
redirects to the login page otherwise. If a user is loaded the original
view is called and continues normally. You’ll use this decorator when
writing the blog views.</p>
</section>
<sectionid="endpoints-and-urls">
<h2>Endpoints and URLs<aclass="headerlink"href="#endpoints-and-urls"title="Link to this heading">¶</a></h2>
<p>The <aclass="reference internal"href="../api.html#flask.url_for"title="flask.url_for"><codeclass="xref py py-func docutils literal notranslate"><spanclass="pre">url_for()</span></code></a> function generates the URL to a view based on a name
and arguments. The name associated with a view is also called the
<em>endpoint</em>, and by default it’s the same as the name of the view
function.</p>
<p>For example, the <codeclass="docutils literal notranslate"><spanclass="pre">hello()</span></code> view that was added to the app
factory earlier in the tutorial has the name <codeclass="docutils literal notranslate"><spanclass="pre">'hello'</span></code> and can be
linked to with <codeclass="docutils literal notranslate"><spanclass="pre">url_for('hello')</span></code>. If it took an argument, which
<p>When using a blueprint, the name of the blueprint is prepended to the
name of the function, so the endpoint for the <codeclass="docutils literal notranslate"><spanclass="pre">login</span></code> function you
wrote above is <codeclass="docutils literal notranslate"><spanclass="pre">'auth.login'</span></code> because you added it to the <codeclass="docutils literal notranslate"><spanclass="pre">'auth'</span></code>
blueprint.</p>
<p>Continue to <aclass="reference internal"href="templates.html"><spanclass="doc">Templates</span></a>.</p>