[pre-commit.ci lite] apply automatic fixes
This commit is contained in:
parent
b3ae3117f9
commit
3d83d8138c
102 changed files with 26790 additions and 26749 deletions
|
|
@ -1,263 +1,239 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" data-content_root="./">
|
||||
<html lang="en" data-content_root="../">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Templates — Flask Documentation (3.2.x)</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=6625fa76" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/flask.css?v=b87c8d14" />
|
||||
<script src="_static/documentation_options.js?v=56528222"></script>
|
||||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script data-project="flask" data-version="3.2.x" src="_static/describe_version.js?v=fa7f30d0"></script>
|
||||
<link rel="icon" href="_static/shortcut-icon.png"/>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="Testing Flask Applications" href="testing.html" />
|
||||
<link rel="prev" title="Keep Developing!" href="tutorial/next.html" />
|
||||
<title>Define and Access the Database — Flask Documentation (3.2.x)</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=6625fa76" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/flask.css?v=b87c8d14" />
|
||||
<script src="../_static/documentation_options.js?v=56528222"></script>
|
||||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||||
<script data-project="flask" data-version="3.2.x" src="../_static/describe_version.js?v=fa7f30d0"></script>
|
||||
<link rel="icon" href="../_static/shortcut-icon.png"/>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Blueprints and Views" href="views.html" />
|
||||
<link rel="prev" title="Application Setup" href="factory.html" />
|
||||
</head><body>
|
||||
<div class="related" role="navigation" aria-label="Related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="py-modindex.html" title="Python Module Index"
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="testing.html" title="Testing Flask Applications"
|
||||
<a href="views.html" title="Blueprints and Views"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="tutorial/next.html" title="Keep Developing!"
|
||||
<a href="factory.html" title="Application Setup"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="index.html">Flask Documentation (3.2.x)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Templates</a></li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Flask Documentation (3.2.x)</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Tutorial</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Define and Access the Database</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="templates">
|
||||
<h1>Templates<a class="headerlink" href="#templates" title="Link to this heading">¶</a></h1>
|
||||
<p>Flask leverages Jinja2 as its template engine. You are obviously free to use
|
||||
a different template engine, but you still have to install Jinja2 to run
|
||||
Flask itself. This requirement is necessary to enable rich extensions.
|
||||
An extension can depend on Jinja2 being present.</p>
|
||||
<p>This section only gives a very quick introduction into how Jinja2
|
||||
is integrated into Flask. If you want information on the template
|
||||
engine’s syntax itself, head over to the official <a class="reference external" href="https://jinja.palletsprojects.com/templates/">Jinja2 Template
|
||||
Documentation</a> for
|
||||
more information.</p>
|
||||
<section id="jinja-setup">
|
||||
<h2>Jinja Setup<a class="headerlink" href="#jinja-setup" title="Link to this heading">¶</a></h2>
|
||||
<p>Unless customized, Jinja2 is configured by Flask as follows:</p>
|
||||
<ul class="simple">
|
||||
<li><p>autoescaping is enabled for all templates ending in <code class="docutils literal notranslate"><span class="pre">.html</span></code>,
|
||||
<code class="docutils literal notranslate"><span class="pre">.htm</span></code>, <code class="docutils literal notranslate"><span class="pre">.xml</span></code>, <code class="docutils literal notranslate"><span class="pre">.xhtml</span></code>, as well as <code class="docutils literal notranslate"><span class="pre">.svg</span></code> when using
|
||||
<code class="xref py py-func docutils literal notranslate"><span class="pre">render_template()</span></code>.</p></li>
|
||||
<li><p>autoescaping is enabled for all strings when using
|
||||
<code class="xref py py-func docutils literal notranslate"><span class="pre">render_template_string()</span></code>.</p></li>
|
||||
<li><p>a template has the ability to opt in/out autoescaping with the
|
||||
<code class="docutils literal notranslate"><span class="pre">{%</span> <span class="pre">autoescape</span> <span class="pre">%}</span></code> tag.</p></li>
|
||||
<li><p>Flask inserts a couple of global functions and helpers into the
|
||||
Jinja2 context, additionally to the values that are present by
|
||||
default.</p></li>
|
||||
</ul>
|
||||
|
||||
<section id="define-and-access-the-database">
|
||||
<h1>Define and Access the Database<a class="headerlink" href="#define-and-access-the-database" title="Link to this heading">¶</a></h1>
|
||||
<p>The application will use a <a class="reference external" href="https://sqlite.org/about.html">SQLite</a> database to store users and posts.
|
||||
Python comes with built-in support for SQLite in the <a class="reference external" href="https://docs.python.org/3/library/sqlite3.html#module-sqlite3" title="(in Python v3.13)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">sqlite3</span></code></a>
|
||||
module.</p>
|
||||
<p>SQLite is convenient because it doesn’t require setting up a separate
|
||||
database server and is built-in to Python. However, if concurrent
|
||||
requests try to write to the database at the same time, they will slow
|
||||
down as each write happens sequentially. Small applications won’t notice
|
||||
this. Once you become big, you may want to switch to a different
|
||||
database.</p>
|
||||
<p>The tutorial doesn’t go into detail about SQL. If you are not familiar
|
||||
with it, the SQLite docs describe the <a class="reference external" href="https://sqlite.org/lang.html">language</a>.</p>
|
||||
<section id="connect-to-the-database">
|
||||
<h2>Connect to the Database<a class="headerlink" href="#connect-to-the-database" title="Link to this heading">¶</a></h2>
|
||||
<p>The first thing to do when working with a SQLite database (and most
|
||||
other Python database libraries) is to create a connection to it. Any
|
||||
queries and operations are performed using the connection, which is
|
||||
closed after the work is finished.</p>
|
||||
<p>In web applications this connection is typically tied to the request. It
|
||||
is created at some point when handling a request, and closed before the
|
||||
response is sent.</p>
|
||||
<div class="literal-block-wrapper docutils container" id="id1">
|
||||
<div class="code-block-caption"><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">flaskr/db.py</span></code></span><a class="headerlink" href="#id1" title="Link to this code">¶</a></div>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">sqlite3</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">datetime</span><span class="w"> </span><span class="kn">import</span> <span class="n">datetime</span>
|
||||
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">click</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">flask</span><span class="w"> </span><span class="kn">import</span> <span class="n">current_app</span><span class="p">,</span> <span class="n">g</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">get_db</span><span class="p">():</span>
|
||||
<span class="k">if</span> <span class="s1">'db'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">g</span><span class="p">:</span>
|
||||
<span class="n">g</span><span class="o">.</span><span class="n">db</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span>
|
||||
<span class="n">current_app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">'DATABASE'</span><span class="p">],</span>
|
||||
<span class="n">detect_types</span><span class="o">=</span><span class="n">sqlite3</span><span class="o">.</span><span class="n">PARSE_DECLTYPES</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">g</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">row_factory</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Row</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">g</span><span class="o">.</span><span class="n">db</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">close_db</span><span class="p">(</span><span class="n">e</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="n">db</span> <span class="o">=</span> <span class="n">g</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">'db'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">db</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">db</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p><a class="reference internal" href="../api.html#flask.g" title="flask.g"><code class="xref py py-data docutils literal notranslate"><span class="pre">g</span></code></a> is a special object that is unique for each request. It is
|
||||
used to store data that might be accessed by multiple functions during
|
||||
the request. The connection is stored and reused instead of creating a
|
||||
new connection if <code class="docutils literal notranslate"><span class="pre">get_db</span></code> is called a second time in the same
|
||||
request.</p>
|
||||
<p><a class="reference internal" href="../api.html#flask.current_app" title="flask.current_app"><code class="xref py py-data docutils literal notranslate"><span class="pre">current_app</span></code></a> is another special object that points to the Flask
|
||||
application handling the request. Since you used an application factory,
|
||||
there is no application object when writing the rest of your code.
|
||||
<code class="docutils literal notranslate"><span class="pre">get_db</span></code> will be called when the application has been created and is
|
||||
handling a request, so <a class="reference internal" href="../api.html#flask.current_app" title="flask.current_app"><code class="xref py py-data docutils literal notranslate"><span class="pre">current_app</span></code></a> can be used.</p>
|
||||
<p><a class="reference external" href="https://docs.python.org/3/library/sqlite3.html#sqlite3.connect" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">sqlite3.connect()</span></code></a> establishes a connection to the file pointed at
|
||||
by the <code class="docutils literal notranslate"><span class="pre">DATABASE</span></code> configuration key. This file doesn’t have to exist
|
||||
yet, and won’t until you initialize the database later.</p>
|
||||
<p><a class="reference external" href="https://docs.python.org/3/library/sqlite3.html#sqlite3.Row" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">sqlite3.Row</span></code></a> tells the connection to return rows that behave
|
||||
like dicts. This allows accessing the columns by name.</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">close_db</span></code> checks if a connection was created by checking if <code class="docutils literal notranslate"><span class="pre">g.db</span></code>
|
||||
was set. If the connection exists, it is closed. Further down you will
|
||||
tell your application about the <code class="docutils literal notranslate"><span class="pre">close_db</span></code> function in the application
|
||||
factory so that it is called after each request.</p>
|
||||
</section>
|
||||
<section id="standard-context">
|
||||
<h2>Standard Context<a class="headerlink" href="#standard-context" title="Link to this heading">¶</a></h2>
|
||||
<p>The following global variables are available within Jinja2 templates
|
||||
by default:</p>
|
||||
<dl class="py data">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">config</span></span></dt>
|
||||
<dd><p>The current configuration object (<a class="reference internal" href="api.html#flask.Flask.config" title="flask.Flask.config"><code class="xref py py-data docutils literal notranslate"><span class="pre">flask.Flask.config</span></code></a>)</p>
|
||||
<details class="changelog">
|
||||
<summary>Changelog</summary><div class="versionchanged">
|
||||
<p><span class="versionmodified changed">Changed in version 0.10: </span>This is now always available, even in imported templates.</p>
|
||||
<section id="create-the-tables">
|
||||
<h2>Create the Tables<a class="headerlink" href="#create-the-tables" title="Link to this heading">¶</a></h2>
|
||||
<p>In SQLite, data is stored in <em>tables</em> and <em>columns</em>. These need to be
|
||||
created before you can store and retrieve data. Flaskr will store users
|
||||
in the <code class="docutils literal notranslate"><span class="pre">user</span></code> table, and posts in the <code class="docutils literal notranslate"><span class="pre">post</span></code> table. Create a file
|
||||
with the SQL commands needed to create empty tables:</p>
|
||||
<div class="literal-block-wrapper docutils container" id="id2">
|
||||
<div class="code-block-caption"><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">flaskr/schema.sql</span></code></span><a class="headerlink" href="#id2" title="Link to this code">¶</a></div>
|
||||
<div class="highlight-sql notranslate"><div class="highlight"><pre><span></span><span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">EXISTS</span><span class="w"> </span><span class="k">user</span><span class="p">;</span>
|
||||
<span class="k">DROP</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">EXISTS</span><span class="w"> </span><span class="n">post</span><span class="p">;</span>
|
||||
|
||||
<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span>
|
||||
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">AUTOINCREMENT</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">username</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">UNIQUE</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span>
|
||||
<span class="p">);</span>
|
||||
|
||||
<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">post</span><span class="w"> </span><span class="p">(</span>
|
||||
<span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">AUTOINCREMENT</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">author_id</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">created</span><span class="w"> </span><span class="k">TIMESTAMP</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="k">CURRENT_TIMESTAMP</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">title</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="k">FOREIGN</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="k">REFERENCES</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">)</span>
|
||||
<span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="versionadded">
|
||||
<p><span class="versionmodified added">Added in version 0.6.</span></p>
|
||||
</div>
|
||||
</details></dd></dl>
|
||||
<p>Add the Python functions that will run these SQL commands to the
|
||||
<code class="docutils literal notranslate"><span class="pre">db.py</span></code> file:</p>
|
||||
<div class="literal-block-wrapper docutils container" id="id3">
|
||||
<div class="code-block-caption"><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">flaskr/db.py</span></code></span><a class="headerlink" href="#id3" title="Link to this code">¶</a></div>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">init_db</span><span class="p">():</span>
|
||||
<span class="n">db</span> <span class="o">=</span> <span class="n">get_db</span><span class="p">()</span>
|
||||
|
||||
<dl class="py data">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">request</span></span></dt>
|
||||
<dd><p>The current request object (<a class="reference internal" href="api.html#flask.request" title="flask.request"><code class="xref py py-class docutils literal notranslate"><span class="pre">flask.request</span></code></a>). This variable is
|
||||
unavailable if the template was rendered without an active request
|
||||
context.</p>
|
||||
</dd></dl>
|
||||
<span class="k">with</span> <span class="n">current_app</span><span class="o">.</span><span class="n">open_resource</span><span class="p">(</span><span class="s1">'schema.sql'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||||
<span class="n">db</span><span class="o">.</span><span class="n">executescript</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'utf8'</span><span class="p">))</span>
|
||||
|
||||
<dl class="py data">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">session</span></span></dt>
|
||||
<dd><p>The current session object (<a class="reference internal" href="api.html#flask.session" title="flask.session"><code class="xref py py-class docutils literal notranslate"><span class="pre">flask.session</span></code></a>). This variable
|
||||
is unavailable if the template was rendered without an active request
|
||||
context.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py data">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">g</span></span></dt>
|
||||
<dd><p>The request-bound object for global variables (<a class="reference internal" href="api.html#flask.g" title="flask.g"><code class="xref py py-data docutils literal notranslate"><span class="pre">flask.g</span></code></a>). This
|
||||
variable is unavailable if the template was rendered without an active
|
||||
request context.</p>
|
||||
</dd></dl>
|
||||
<span class="nd">@click</span><span class="o">.</span><span class="n">command</span><span class="p">(</span><span class="s1">'init-db'</span><span class="p">)</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">init_db_command</span><span class="p">():</span>
|
||||
<span class="w"> </span><span class="sd">"""Clear the existing data and create new tables."""</span>
|
||||
<span class="n">init_db</span><span class="p">()</span>
|
||||
<span class="n">click</span><span class="o">.</span><span class="n">echo</span><span class="p">(</span><span class="s1">'Initialized the database.'</span><span class="p">)</span>
|
||||
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">url_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
|
||||
<dd><p>The <a class="reference internal" href="api.html#flask.url_for" title="flask.url_for"><code class="xref py py-func docutils literal notranslate"><span class="pre">flask.url_for()</span></code></a> function.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dt class="sig sig-object py">
|
||||
<span class="sig-name descname"><span class="pre">get_flashed_messages</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
|
||||
<dd><p>The <a class="reference internal" href="api.html#flask.get_flashed_messages" title="flask.get_flashed_messages"><code class="xref py py-func docutils literal notranslate"><span class="pre">flask.get_flashed_messages()</span></code></a> function.</p>
|
||||
</dd></dl>
|
||||
<span class="n">sqlite3</span><span class="o">.</span><span class="n">register_converter</span><span class="p">(</span>
|
||||
<span class="s2">"timestamp"</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">v</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">v</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
|
||||
<span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p><a class="reference internal" href="../api.html#flask.Flask.open_resource" title="flask.Flask.open_resource"><code class="xref py py-meth docutils literal notranslate"><span class="pre">open_resource()</span></code></a> opens a file relative to
|
||||
the <code class="docutils literal notranslate"><span class="pre">flaskr</span></code> package, which is useful since you won’t necessarily know
|
||||
where that location is when deploying the application later. <code class="docutils literal notranslate"><span class="pre">get_db</span></code>
|
||||
returns a database connection, which is used to execute the commands
|
||||
read from the file.</p>
|
||||
<p><a class="reference external" href="https://click.palletsprojects.com/en/stable/api/#click.command" title="(in Click v8.1.x)"><code class="xref py py-func docutils literal notranslate"><span class="pre">click.command()</span></code></a> defines a command line command called <code class="docutils literal notranslate"><span class="pre">init-db</span></code>
|
||||
that calls the <code class="docutils literal notranslate"><span class="pre">init_db</span></code> function and shows a success message to the
|
||||
user. You can read <a class="reference internal" href="../cli.html"><span class="doc">Command Line Interface</span></a> to learn more about writing commands.</p>
|
||||
<p>The call to <a class="reference external" href="https://docs.python.org/3/library/sqlite3.html#sqlite3.register_converter" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">sqlite3.register_converter()</span></code></a> tells Python how to
|
||||
interpret timestamp values in the database. We convert the value to a
|
||||
<a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.datetime" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime.datetime</span></code></a>.</p>
|
||||
</section>
|
||||
<section id="register-with-the-application">
|
||||
<h2>Register with the Application<a class="headerlink" href="#register-with-the-application" title="Link to this heading">¶</a></h2>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">close_db</span></code> and <code class="docutils literal notranslate"><span class="pre">init_db_command</span></code> functions need to be registered
|
||||
with the application instance; otherwise, they won’t be used by the
|
||||
application. However, since you’re using a factory function, that
|
||||
instance isn’t available when writing the functions. Instead, write a
|
||||
function that takes an application and does the registration.</p>
|
||||
<div class="literal-block-wrapper docutils container" id="id4">
|
||||
<div class="code-block-caption"><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">flaskr/db.py</span></code></span><a class="headerlink" href="#id4" title="Link to this code">¶</a></div>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">init_app</span><span class="p">(</span><span class="n">app</span><span class="p">):</span>
|
||||
<span class="n">app</span><span class="o">.</span><span class="n">teardown_appcontext</span><span class="p">(</span><span class="n">close_db</span><span class="p">)</span>
|
||||
<span class="n">app</span><span class="o">.</span><span class="n">cli</span><span class="o">.</span><span class="n">add_command</span><span class="p">(</span><span class="n">init_db_command</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<p><a class="reference internal" href="../api.html#flask.Flask.teardown_appcontext" title="flask.Flask.teardown_appcontext"><code class="xref py py-meth docutils literal notranslate"><span class="pre">app.teardown_appcontext()</span></code></a> tells
|
||||
Flask to call that function when cleaning up after returning the
|
||||
response.</p>
|
||||
<p><a class="reference external" href="https://click.palletsprojects.com/en/stable/api/#click.Group.add_command" title="(in Click v8.1.x)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">app.cli.add_command()</span></code></a> adds a new
|
||||
command that can be called with the <code class="docutils literal notranslate"><span class="pre">flask</span></code> command.</p>
|
||||
<p>Import and call this function from the factory. Place the new code at
|
||||
the end of the factory function before returning the app.</p>
|
||||
<div class="literal-block-wrapper docutils container" id="id5">
|
||||
<div class="code-block-caption"><span class="caption-text"><code class="docutils literal notranslate"><span class="pre">flaskr/__init__.py</span></code></span><a class="headerlink" href="#id5" title="Link to this code">¶</a></div>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">create_app</span><span class="p">():</span>
|
||||
<span class="n">app</span> <span class="o">=</span> <span class="o">...</span>
|
||||
<span class="c1"># existing code omitted</span>
|
||||
|
||||
<div class="admonition-the-jinja-context-behavior admonition">
|
||||
<p class="admonition-title">The Jinja Context Behavior</p>
|
||||
<p>These variables are added to the context of variables, they are not
|
||||
global variables. The difference is that by default these will not
|
||||
show up in the context of imported templates. This is partially caused
|
||||
by performance considerations, partially to keep things explicit.</p>
|
||||
<p>What does this mean for you? If you have a macro you want to import,
|
||||
that needs to access the request object you have two possibilities:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p>you explicitly pass the request to the macro as parameter, or
|
||||
the attribute of the request object you are interested in.</p></li>
|
||||
<li><p>you import the macro “with context”.</p></li>
|
||||
</ol>
|
||||
<p>Importing with context looks like this:</p>
|
||||
<div class="highlight-jinja notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">from</span> <span class="s1">'_helpers.html'</span> <span class="k">import</span> <span class="nv">my_macro</span> <span class="k">with context</span> <span class="cp">%}</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">.</span><span class="w"> </span><span class="kn">import</span> <span class="n">db</span>
|
||||
<span class="n">db</span><span class="o">.</span><span class="n">init_app</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">app</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="controlling-autoescaping">
|
||||
<h2>Controlling Autoescaping<a class="headerlink" href="#controlling-autoescaping" title="Link to this heading">¶</a></h2>
|
||||
<p>Autoescaping is the concept of automatically escaping special characters
|
||||
for you. Special characters in the sense of HTML (or XML, and thus XHTML)
|
||||
are <code class="docutils literal notranslate"><span class="pre">&</span></code>, <code class="docutils literal notranslate"><span class="pre">></span></code>, <code class="docutils literal notranslate"><span class="pre"><</span></code>, <code class="docutils literal notranslate"><span class="pre">"</span></code> as well as <code class="docutils literal notranslate"><span class="pre">'</span></code>. Because these characters
|
||||
carry specific meanings in documents on their own you have to replace them
|
||||
by so called “entities” if you want to use them for text. Not doing so
|
||||
would not only cause user frustration by the inability to use these
|
||||
characters in text, but can also lead to security problems. (see
|
||||
<a class="reference internal" href="web-security.html#security-xss"><span class="std std-ref">Cross-Site Scripting (XSS)</span></a>)</p>
|
||||
<p>Sometimes however you will need to disable autoescaping in templates.
|
||||
This can be the case if you want to explicitly inject HTML into pages, for
|
||||
example if they come from a system that generates secure HTML like a
|
||||
markdown to HTML converter.</p>
|
||||
<p>There are three ways to accomplish that:</p>
|
||||
<ul class="simple">
|
||||
<li><p>In the Python code, wrap the HTML string in a <code class="xref py py-class docutils literal notranslate"><span class="pre">Markup</span></code>
|
||||
object before passing it to the template. This is in general the
|
||||
recommended way.</p></li>
|
||||
<li><p>Inside the template, use the <code class="docutils literal notranslate"><span class="pre">|safe</span></code> filter to explicitly mark a
|
||||
string as safe HTML (<code class="docutils literal notranslate"><span class="pre">{{</span> <span class="pre">myvariable|safe</span> <span class="pre">}}</span></code>)</p></li>
|
||||
<li><p>Temporarily disable the autoescape system altogether.</p></li>
|
||||
</ul>
|
||||
<p>To disable the autoescape system in templates, you can use the <code class="docutils literal notranslate"><span class="pre">{%</span>
|
||||
<span class="pre">autoescape</span> <span class="pre">%}</span></code> block:</p>
|
||||
<div class="highlight-html+jinja notranslate"><div class="highlight"><pre><span></span><span class="cp">{%</span> <span class="k">autoescape</span> <span class="kp">false</span> <span class="cp">%}</span>
|
||||
<span class="p"><</span><span class="nt">p</span><span class="p">></span>autoescaping is disabled here
|
||||
<span class="p"><</span><span class="nt">p</span><span class="p">></span><span class="cp">{{</span> <span class="nv">will_not_be_escaped</span> <span class="cp">}}</span>
|
||||
<span class="cp">{%</span> <span class="k">endautoescape</span> <span class="cp">%}</span>
|
||||
<section id="initialize-the-database-file">
|
||||
<h2>Initialize the Database File<a class="headerlink" href="#initialize-the-database-file" title="Link to this heading">¶</a></h2>
|
||||
<p>Now that <code class="docutils literal notranslate"><span class="pre">init-db</span></code> has been registered with the app, it can be called
|
||||
using the <code class="docutils literal notranslate"><span class="pre">flask</span></code> command, similar to the <code class="docutils literal notranslate"><span class="pre">run</span></code> command from the
|
||||
previous page.</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>If you’re still running the server from the previous page, you can
|
||||
either stop the server, or run this command in a new terminal. If
|
||||
you use a new terminal, remember to change to your project directory
|
||||
and activate the env as described in <a class="reference internal" href="../installation.html"><span class="doc">Installation</span></a>.</p>
|
||||
</div>
|
||||
<p>Run the <code class="docutils literal notranslate"><span class="pre">init-db</span></code> command:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ flask --app flaskr init-db
|
||||
Initialized the database.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Whenever you do this, please be very cautious about the variables you are
|
||||
using in this block.</p>
|
||||
</section>
|
||||
<section id="registering-filters">
|
||||
<span id="id1"></span><h2>Registering Filters<a class="headerlink" href="#registering-filters" title="Link to this heading">¶</a></h2>
|
||||
<p>If you want to register your own filters in Jinja2 you have two ways to do
|
||||
that. You can either put them by hand into the
|
||||
<a class="reference internal" href="api.html#flask.Flask.jinja_env" title="flask.Flask.jinja_env"><code class="xref py py-attr docutils literal notranslate"><span class="pre">jinja_env</span></code></a> of the application or use the
|
||||
<a class="reference internal" href="api.html#flask.Flask.template_filter" title="flask.Flask.template_filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">template_filter()</span></code></a> decorator.</p>
|
||||
<p>The two following examples work the same and both reverse an object:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@app</span><span class="o">.</span><span class="n">template_filter</span><span class="p">(</span><span class="s1">'reverse'</span><span class="p">)</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">reverse_filter</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">s</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">reverse_filter</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">s</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
||||
<span class="n">app</span><span class="o">.</span><span class="n">jinja_env</span><span class="o">.</span><span class="n">filters</span><span class="p">[</span><span class="s1">'reverse'</span><span class="p">]</span> <span class="o">=</span> <span class="n">reverse_filter</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In case of the decorator the argument is optional if you want to use the
|
||||
function name as name of the filter. Once registered, you can use the filter
|
||||
in your templates in the same way as Jinja2’s builtin filters, for example if
|
||||
you have a Python list in context called <code class="code docutils literal notranslate"><span class="pre">mylist</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="o">%</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">mylist</span> <span class="o">|</span> <span class="n">reverse</span> <span class="o">%</span><span class="p">}</span>
|
||||
<span class="p">{</span><span class="o">%</span> <span class="n">endfor</span> <span class="o">%</span><span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="context-processors">
|
||||
<h2>Context Processors<a class="headerlink" href="#context-processors" title="Link to this heading">¶</a></h2>
|
||||
<p>To inject new variables automatically into the context of a template,
|
||||
context processors exist in Flask. Context processors run before the
|
||||
template is rendered and have the ability to inject new values into the
|
||||
template context. A context processor is a function that returns a
|
||||
dictionary. The keys and values of this dictionary are then merged with
|
||||
the template context, for all templates in the app:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@app</span><span class="o">.</span><span class="n">context_processor</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">inject_user</span><span class="p">():</span>
|
||||
<span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">user</span><span class="o">=</span><span class="n">g</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The context processor above makes a variable called <code class="code docutils literal notranslate"><span class="pre">user</span></code> available in
|
||||
the template with the value of <code class="code docutils literal notranslate"><span class="pre">g.user</span></code>. This example is not very
|
||||
interesting because <code class="code docutils literal notranslate"><span class="pre">g</span></code> is available in templates anyways, but it gives an
|
||||
idea how this works.</p>
|
||||
<p>Variables are not limited to values; a context processor can also make
|
||||
functions available to templates (since Python allows passing around
|
||||
functions):</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@app</span><span class="o">.</span><span class="n">context_processor</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">utility_processor</span><span class="p">():</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">format_price</span><span class="p">(</span><span class="n">amount</span><span class="p">,</span> <span class="n">currency</span><span class="o">=</span><span class="s2">"€"</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">amount</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}{</span><span class="n">currency</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">format_price</span><span class="o">=</span><span class="n">format_price</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The context processor above makes the <code class="code docutils literal notranslate"><span class="pre">format_price</span></code> function available to all
|
||||
templates:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{{</span> <span class="n">format_price</span><span class="p">(</span><span class="mf">0.33</span><span class="p">)</span> <span class="p">}}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You could also build <code class="code docutils literal notranslate"><span class="pre">format_price</span></code> as a template filter (see
|
||||
<a class="reference internal" href="#registering-filters"><span class="std std-ref">Registering Filters</span></a>), but this demonstrates how to pass functions in a
|
||||
context processor.</p>
|
||||
</section>
|
||||
<section id="streaming">
|
||||
<h2>Streaming<a class="headerlink" href="#streaming" title="Link to this heading">¶</a></h2>
|
||||
<p>It can be useful to not render the whole template as one complete
|
||||
string, instead render it as a stream, yielding smaller incremental
|
||||
strings. This can be used for streaming HTML in chunks to speed up
|
||||
initial page load, or to save memory when rendering a very large
|
||||
template.</p>
|
||||
<p>The Jinja2 template engine supports rendering a template piece
|
||||
by piece, returning an iterator of strings. Flask provides the
|
||||
<a class="reference internal" href="api.html#flask.stream_template" title="flask.stream_template"><code class="xref py py-func docutils literal notranslate"><span class="pre">stream_template()</span></code></a> and <a class="reference internal" href="api.html#flask.stream_template_string" title="flask.stream_template_string"><code class="xref py py-func docutils literal notranslate"><span class="pre">stream_template_string()</span></code></a>
|
||||
functions to make this easier to use.</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">flask</span><span class="w"> </span><span class="kn">import</span> <span class="n">stream_template</span>
|
||||
|
||||
<span class="nd">@app</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"/timeline"</span><span class="p">)</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">timeline</span><span class="p">():</span>
|
||||
<span class="k">return</span> <span class="n">stream_template</span><span class="p">(</span><span class="s2">"timeline.html"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>These functions automatically apply the
|
||||
<a class="reference internal" href="api.html#flask.stream_with_context" title="flask.stream_with_context"><code class="xref py py-func docutils literal notranslate"><span class="pre">stream_with_context()</span></code></a> wrapper if a request is active, so
|
||||
that it remains available in the template.</p>
|
||||
<p>There will now be a <code class="docutils literal notranslate"><span class="pre">flaskr.sqlite</span></code> file in the <code class="docutils literal notranslate"><span class="pre">instance</span></code> folder in
|
||||
your project.</p>
|
||||
<p>Continue to <a class="reference internal" href="views.html"><span class="doc">Blueprints and Views</span></a>.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
|
@ -269,38 +245,39 @@ that it remains available in the template.</p>
|
|||
<span id="sidebar-top"></span>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
|
||||
<p class="logo"><a href="index.html">
|
||||
<img class="logo" src="_static/flask-vertical.png" alt="Logo of Flask"/>
|
||||
|
||||
|
||||
<p class="logo"><a href="../index.html">
|
||||
<img class="logo" src="../_static/flask-vertical.png" alt="Logo of Flask"/>
|
||||
</a></p>
|
||||
|
||||
|
||||
|
||||
<h3>Contents</h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Templates</a><ul>
|
||||
<li><a class="reference internal" href="#jinja-setup">Jinja Setup</a></li>
|
||||
<li><a class="reference internal" href="#standard-context">Standard Context</a></li>
|
||||
<li><a class="reference internal" href="#controlling-autoescaping">Controlling Autoescaping</a></li>
|
||||
<li><a class="reference internal" href="#registering-filters">Registering Filters</a></li>
|
||||
<li><a class="reference internal" href="#context-processors">Context Processors</a></li>
|
||||
<li><a class="reference internal" href="#streaming">Streaming</a></li>
|
||||
<li><a class="reference internal" href="#">Define and Access the Database</a><ul>
|
||||
<li><a class="reference internal" href="#connect-to-the-database">Connect to the Database</a></li>
|
||||
<li><a class="reference internal" href="#create-the-tables">Create the Tables</a></li>
|
||||
<li><a class="reference internal" href="#register-with-the-application">Register with the Application</a></li>
|
||||
<li><a class="reference internal" href="#initialize-the-database-file">Initialize the Database File</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Overview</a>
|
||||
<li><a href="../index.html">Overview</a>
|
||||
<ul>
|
||||
<li>Previous: <a href="tutorial/next.html" title="previous chapter">Keep Developing!</a>
|
||||
<li>Next: <a href="testing.html" title="next chapter">Testing Flask Applications</a>
|
||||
<li><a href="index.html">Tutorial</a>
|
||||
<ul>
|
||||
<li>Previous: <a href="factory.html" title="previous chapter">Application Setup</a>
|
||||
<li>Next: <a href="views.html" title="next chapter">Blueprints and Views</a></ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<search id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<form class="search" action="../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
|
|
@ -316,4 +293,4 @@ that it remains available in the template.</p>
|
|||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.1.3.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue