Minor updates
This commit is contained in:
@ -683,10 +683,12 @@
|
||||
|
||||
|
||||
<main class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5 bd-content" role="main">
|
||||
<h1 class="bd-title" id="content">Black Dashboard Flask</h1>
|
||||
<p class="bd-lead"></p>
|
||||
<h1 id="black-dashboard-flask"><a href="https://www.creative-tim.com/product/black-dashboard-flask">Black Dashboard Flask</a></h1>
|
||||
|
||||
<h1 class="bd-title" id="content">
|
||||
<a href="https://www.creative-tim.com/product/black-dashboard-flask">Black Dashboard Flask</a>
|
||||
</h1>
|
||||
|
||||
<p class="bd-lead"></p>
|
||||
<hr />
|
||||
<p>Black Dashboard Black is a free Bootstrap 4 Admin Template for Django - Features:</p>
|
||||
|
||||
<ul>
|
||||
@ -702,9 +704,9 @@
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://www.creative-tim.com/product/black-dashboard-flask">Black Dashboard Flask</a> - product page</li>
|
||||
<li><a href="https://www.creative-tim.com/live/black-dashboard-flask">Black Dashboard Flask Demo</a> - LIVE App, default login credentials ** <em>test / pass</em> **</li>
|
||||
<li><a href="https://github.com/creativetimofficial/black-dashboard-flask/">Black Dashboard Flask Sources</a> - MIT License, released on Github</li>
|
||||
<li><a target="_blank" href="https://www.creative-tim.com/product/black-dashboard-flask">Black Dashboard Flask</a> - product page</li>
|
||||
<li><a target="_blank" href="https://www.creative-tim.com/live/black-dashboard-flask">Black Dashboard Flask Demo</a> - LIVE App, default login credentials ** <em>test / pass</em> **</li>
|
||||
<li><a target="_blank" href="https://github.com/creativetimofficial/black-dashboard-flask/">Black Dashboard Flask Sources</a> - MIT License, released on Github</li>
|
||||
<li>Tutorials
|
||||
<ul>
|
||||
<li><a href="./setup-centos-for-development.html">Set up <code class="highlighter-rouge">CentOS</code> for development</a></li>
|
||||
@ -755,17 +757,9 @@ Classified as a microframework, Flask is written in Python and it does not requi
|
||||
<p>Check <a href="https://www.python.org/">Python</a> version (using the terminal)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge">
|
||||
<div class="highlight">
|
||||
<pre class="highlight">
|
||||
<code>
|
||||
<span class="nv">$ </span><span class="c"># Check Python version</span>
|
||||
<span class="nv">$ </span>python <span class="nt">--version</span>
|
||||
Python 3.7.2 <span class="c"># <--- All good</span>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"> $ # Check Python version
|
||||
$ python --version
|
||||
Python 3.7.2 # <span class="nt"><---</span> <span class="na">All</span> <span class="na">good</span></code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -773,10 +767,9 @@ Python 3.7.2 <span class="c"># <--- All good</span>
|
||||
<p>Check <a href="https://git-scm.com/">GIT</a> command tool (using the terminal)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="c"># Check git</span>
|
||||
<span class="nv">$ </span>git <span class="nt">--version</span>
|
||||
<span class="nv">$ </span>git version 2.10.1.windows.1 <span class="c"># <--- All good</span>
|
||||
</code></pre></div></div>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html">$ # Check git
|
||||
$ git --version
|
||||
$ git version 2.10.1.windows.1 # <span class="nt"><---</span> <span class="na">All</span> <span class="na">good</span></code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -808,36 +801,35 @@ Python 3.7.2 <span class="c"># <--- All good</span>
|
||||
<p><strong>Change the current directory</strong> to <code class="highlighter-rouge">source code</code> directory</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="c"># Make sure you are running the commands INSIDE source code directory</span>
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Create and activate a Virtualenv (Unix based systems)</span>
|
||||
<span class="nv">$ </span>virtualenv <span class="nb">env</span>
|
||||
<span class="nv">$ </span><span class="nb">source env</span>/bin/activate
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Create and activate a Virtualenv (Windows based systems)</span>
|
||||
<span class="nv">$ </span><span class="c"># virtualenv env</span>
|
||||
<span class="nv">$ </span><span class="c"># .\env\Scripts\activate</span>
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Install requirements</span>
|
||||
<span class="nv">$ </span>pip3 <span class="nb">install</span> <span class="nt">-r</span> requirements.txt
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Set the FLASK_APP environment variable</span>
|
||||
<span class="nv">$ </span><span class="o">(</span>Unix/Mac<span class="o">)</span> <span class="nb">export </span><span class="nv">FLASK_APP</span><span class="o">=</span>run.py
|
||||
<span class="nv">$ </span><span class="o">(</span>Windows<span class="o">)</span> <span class="nb">set </span><span class="nv">FLASK_APP</span><span class="o">=</span>run.py
|
||||
<span class="nv">$ </span><span class="o">(</span>Powershell<span class="o">)</span> <span class="nv">$env</span>:FLASK_APP <span class="o">=</span> <span class="s2">".</span><span class="se">\r</span><span class="s2">un.py"</span>
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Set up the DEBUG environment</span>
|
||||
<span class="nv">$ </span><span class="c"># (Unix/Mac) export FLASK_ENV=development</span>
|
||||
<span class="nv">$ </span><span class="c"># (Windows) set FLASK_ENV=development</span>
|
||||
<span class="nv">$ </span><span class="c"># (Powershell) $env:FLASK_ENV = "development"</span>
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Run the application</span>
|
||||
<span class="nv">$ </span><span class="c"># --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1)</span>
|
||||
<span class="nv">$ </span><span class="c"># --port=5000 - specify the app port (default 5000) </span>
|
||||
<span class="nv">$ </span>flask run <span class="nt">--host</span><span class="o">=</span>0.0.0.0 <span class="nt">--port</span><span class="o">=</span>5000
|
||||
<span class="err">$</span>
|
||||
<span class="nv">$ </span><span class="c"># Access the app in browser: http://127.0.0.1:5000/</span>
|
||||
</code></pre></div></div>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html">$ # Make sure you are running the commands INSIDE source code directory
|
||||
$
|
||||
$ # Create and activate a Virtualenv (Unix based systems)
|
||||
$ virtualenv env
|
||||
$ source env/bin/activate
|
||||
$
|
||||
$ # Create and activate a Virtualenv (Windows based systems)
|
||||
$ # virtualenv env
|
||||
$ # .\env\Scripts\activate
|
||||
$
|
||||
$ # Install requirements
|
||||
$ pip3 install -r requirements.txt
|
||||
$
|
||||
$ # Set the FLASK_APP environment variable
|
||||
$ (Unix/Mac) export FLASK_APP=run.py
|
||||
$ (Windows) set FLASK_APP=run.py
|
||||
$ (Powershell) $env:FLASK_APP = ".\run.py"
|
||||
$
|
||||
$ # Set up the DEBUG environment
|
||||
$ # (Unix/Mac) export FLASK_ENV=development
|
||||
$ # (Windows) set FLASK_ENV=development
|
||||
$ # (Powershell) $env:FLASK_ENV = "development"
|
||||
$
|
||||
$ # Run the application
|
||||
$ # --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1)
|
||||
$ # --port=5000 - specify the app port (default 5000)
|
||||
$ flask run --host=0.0.0.0 --port=5000
|
||||
$
|
||||
$ # Access the app in browser: http://127.0.0.1:5000/</code></pre></figure>
|
||||
|
||||
<p>At this point, we can visit the app in the browser <strong><code class="highlighter-rouge">http://127.0.0.1:5000/</code></strong>.
|
||||
By default, the app will redirect guest users to the login page. To access the private pages:</p>
|
||||
@ -854,24 +846,25 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
|
||||
<p>Starter uses a simple codebase (no Blueprints) with a structure presented bellow:</p>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>< PROJECT ROOT <span class="o">></span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><</span> <span class="nt">PROJECT</span> <span class="na">ROOT</span> <span class="nt">></span>
|
||||
|
|
||||
|-- app/ <span class="c"># Implements app logic</span>
|
||||
| |-- base/ <span class="c"># Base Blueprint - handles the authentication</span>
|
||||
| |-- home/ <span class="c"># Home Blueprint - serve UI Kit pages</span>
|
||||
|-- app/ # Implements app logic
|
||||
| |-- base/ # Base Blueprint - handles the authentication
|
||||
| |-- home/ # Home Blueprint - serve UI Kit pages
|
||||
| |
|
||||
| __init__.py <span class="c"># Initialize the app</span>
|
||||
| __init__.py # Initialize the app
|
||||
|
|
||||
|-- requirements.txt <span class="c"># Development modules - SQLite storage</span>
|
||||
|-- requirements-mysql.txt <span class="c"># Production modules - Mysql DMBS</span>
|
||||
|-- requirements-pqsql.txt <span class="c"># Production modules - PostgreSql DMBS</span>
|
||||
|-- requirements.txt # Development modules - SQLite storage
|
||||
|-- requirements-mysql.txt # Production modules - Mysql DMBS
|
||||
|-- requirements-pqsql.txt # Production modules - PostgreSql DMBS
|
||||
|
|
||||
|-- .env <span class="c"># Inject Configuration via Environment</span>
|
||||
|-- config.py <span class="c"># Set up the app</span>
|
||||
|-- run.py <span class="c"># Start the app - WSGI gateway</span>
|
||||
|-- .env # Inject Configuration via Environment
|
||||
|-- config.py # Set up the app
|
||||
|-- run.py # Start the app - WSGI gateway
|
||||
|
|
||||
|-- <span class="k">************************************************************************</span>
|
||||
</code></pre></div></div>
|
||||
|-- ************************************************************************
|
||||
|
||||
</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -897,22 +890,20 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
<p><strong><code class="highlighter-rouge">.env</code></strong> (saved in the root of the project)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># File: `.env`</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># File: `.env`
|
||||
|
||||
<span class="nv">DEBUG</span><span class="o">=</span>True <span class="c"># Enable/Disable the development environment</span>
|
||||
DEBUG=True # Enable/Disable the development environment
|
||||
|
||||
<span class="nv">SECRET_KEY</span><span class="o">=</span>S3cr3t_Key <span class="c"># The Key used by Flask to encrypt session information</span>
|
||||
SECRET_KEY=S3cr3t_Key # The Key used by Flask to encrypt session information
|
||||
|
||||
<span class="c"># Database production settings (If DEBUG=False)</span>
|
||||
# Database production settings (If DEBUG=False)
|
||||
|
||||
<span class="nv">DB_ENGINE</span><span class="o">=</span>postgresql <span class="c"># DBMS</span>
|
||||
<span class="nv">DB_NAME</span><span class="o">=</span>appseed-flask <span class="c"># Database Name</span>
|
||||
<span class="nv">DB_HOST</span><span class="o">=</span>localhost <span class="c"># Database Host</span>
|
||||
<span class="nv">DB_PORT</span><span class="o">=</span>5432 <span class="c"># Database Port</span>
|
||||
<span class="nv">DB_USERNAME</span><span class="o">=</span>appseed <span class="c"># DB Username</span>
|
||||
<span class="nv">DB_PASS</span><span class="o">=</span>pass <span class="c"># DB Password</span>
|
||||
|
||||
</code></pre></div></div>
|
||||
DB_ENGINE=postgresql # DBMS
|
||||
DB_NAME=appseed-flask # Database Name
|
||||
DB_HOST=localhost # Database Host
|
||||
DB_PORT=5432 # Database Port
|
||||
DB_USERNAME=appseed # DB Username
|
||||
DB_PASS=pass # DB Password</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -920,16 +911,15 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
<p><strong><code class="highlighter-rouge">run.py</code></strong> (simplified version)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># File: run.py
|
||||
</span>
|
||||
<span class="n">DEBUG</span> <span class="o">=</span> <span class="n">config</span><span class="p">(</span><span class="s">'DEBUG'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># File: run.py
|
||||
|
||||
<span class="c1"># Create the WSGI app, using the app factory pattern
|
||||
</span><span class="n">app</span> <span class="o">=</span> <span class="n">create_app</span><span class="p">(</span> <span class="n">app_config</span> <span class="p">)</span>
|
||||
DEBUG = config('DEBUG', default=True)
|
||||
|
||||
<span class="c1"># Migrate automaticaly the app using Flask Migrate library
|
||||
</span><span class="n">Migrate</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span>
|
||||
</code></pre></div></div>
|
||||
# Create the WSGI app, using the app factory pattern
|
||||
app = create_app( app_config )
|
||||
|
||||
# Migrate automaticaly the app using Flask Migrate library
|
||||
Migrate(app, db)</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -937,37 +927,36 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
<p><strong><code class="highlighter-rouge">app/__init__.py</code></strong> (simplified version)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># File: app/__init__.py
|
||||
</span>
|
||||
<span class="n">db</span> <span class="o">=</span> <span class="n">SQLAlchemy</span><span class="p">()</span> <span class="c1"># Invoke SQLAlchemy
|
||||
</span><span class="n">login_manager</span> <span class="o">=</span> <span class="n">LoginManager</span><span class="p">()</span> <span class="c1"># Invoke Login Manager
|
||||
</span>
|
||||
<span class="k">def</span> <span class="nf">register_extensions</span><span class="p">(</span><span class="n">app</span><span class="p">):</span>
|
||||
<span class="n">db</span><span class="p">.</span><span class="n">init_app</span><span class="p">(</span><span class="n">app</span><span class="p">)</span> <span class="c1"># Inject SQLAlchemy magic
|
||||
</span> <span class="n">login_manager</span><span class="p">.</span><span class="n">init_app</span><span class="p">(</span><span class="n">app</span><span class="p">)</span> <span class="c1"># Add Login Manager to the app
|
||||
</span>
|
||||
<span class="c1"># Register app blueprints: `base`, `home`
|
||||
</span><span class="k">def</span> <span class="nf">register_blueprints</span><span class="p">(</span><span class="n">app</span><span class="p">):</span>
|
||||
<span class="k">for</span> <span class="n">module_name</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'base'</span><span class="p">,</span> <span class="s">'home'</span><span class="p">):</span>
|
||||
<span class="n">module</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="s">'app.{}.routes'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">module_name</span><span class="p">))</span>
|
||||
<span class="n">app</span><span class="p">.</span><span class="n">register_blueprint</span><span class="p">(</span><span class="n">module</span><span class="p">.</span><span class="n">blueprint</span><span class="p">)</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># File: app/__init__.py
|
||||
|
||||
<span class="c1"># Create the tables (automaticaly)
|
||||
</span><span class="k">def</span> <span class="nf">configure_database</span><span class="p">(</span><span class="n">app</span><span class="p">):</span>
|
||||
db = SQLAlchemy() # Invoke SQLAlchemy
|
||||
login_manager = LoginManager() # Invoke Login Manager
|
||||
|
||||
<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">before_first_request</span>
|
||||
<span class="k">def</span> <span class="nf">initialize_database</span><span class="p">():</span>
|
||||
<span class="n">db</span><span class="p">.</span><span class="n">create_all</span><span class="p">()</span>
|
||||
def register_extensions(app):
|
||||
db.init_app(app) # Inject SQLAlchemy magic
|
||||
login_manager.init_app(app) # Add Login Manager to the app
|
||||
|
||||
<span class="c1"># Create the WSGI app using the factory pattern
|
||||
</span><span class="k">def</span> <span class="nf">create_app</span><span class="p">(</span><span class="n">config</span><span class="p">):</span>
|
||||
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">,</span> <span class="n">static_folder</span><span class="o">=</span><span class="s">'base/static'</span><span class="p">)</span>
|
||||
<span class="n">app</span><span class="p">.</span><span class="n">config</span><span class="p">.</span><span class="n">from_object</span><span class="p">(</span><span class="n">config</span><span class="p">)</span>
|
||||
<span class="n">register_extensions</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
|
||||
<span class="n">register_blueprints</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
|
||||
<span class="n">configure_database</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">app</span>
|
||||
</code></pre></div></div>
|
||||
# Register app blueprints: `base`, `home`
|
||||
def register_blueprints(app):
|
||||
for module_name in ('base', 'home'):
|
||||
module = import_module('app.{}.routes'.format(module_name))
|
||||
app.register_blueprint(module.blueprint)
|
||||
|
||||
# Create the tables (automaticaly)
|
||||
def configure_database(app):
|
||||
|
||||
@app.before_first_request
|
||||
def initialize_database():
|
||||
db.create_all()
|
||||
|
||||
# Create the WSGI app using the factory pattern
|
||||
def create_app(config):
|
||||
app = Flask(__name__, static_folder='base/static')
|
||||
app.config.from_object(config)
|
||||
register_extensions(app)
|
||||
register_blueprints(app)
|
||||
configure_database(app)
|
||||
return app</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1000,40 +989,39 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
<p><strong>App / Base Blueprint</strong> structure</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>< PROJECT ROOT <span class="o">></span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><</span> <span class="nt">PROJECT</span> <span class="na">ROOT</span> <span class="nt">></span>
|
||||
|
|
||||
|-- app/
|
||||
| |-- home/ <span class="c"># Home Blueprint - serve app pages (private area)</span>
|
||||
| |-- base/ <span class="c"># Base Blueprint - handles the authentication</span>
|
||||
| |-- home/ # Home Blueprint - serve app pages (private area)
|
||||
| |-- base/ # Base Blueprint - handles the authentication
|
||||
| |-- static/
|
||||
| | |-- <css, JS, images> <span class="c"># CSS files, Javascripts files</span>
|
||||
| | |-- <span class="nt"><css</span><span class="err">,</span> <span class="na">JS</span><span class="err">,</span> <span class="na">images</span><span class="nt">></span> # CSS files, Javascripts files
|
||||
| |
|
||||
| |-- templates/ <span class="c"># Templates used to render pages</span>
|
||||
| |-- templates/ # Templates used to render pages
|
||||
| |
|
||||
| |-- includes/ <span class="c">#</span>
|
||||
| | |-- navigation.html <span class="c"># Top menu component</span>
|
||||
| | |-- sidebar.html <span class="c"># Sidebar component</span>
|
||||
| | |-- footer.html <span class="c"># App Footer</span>
|
||||
| | |-- scripts.html <span class="c"># Scripts common to all pages</span>
|
||||
| |-- includes/ #
|
||||
| | |-- navigation.html # Top menu component
|
||||
| | |-- sidebar.html # Sidebar component
|
||||
| | |-- footer.html # App Footer
|
||||
| | |-- scripts.html # Scripts common to all pages
|
||||
| |
|
||||
| |-- layouts/ <span class="c"># Master pages</span>
|
||||
| | |-- base-fullscreen.html <span class="c"># Used by Authentication pages</span>
|
||||
| | |-- base.html <span class="c"># Used by common pages</span>
|
||||
| |-- layouts/ # Master pages
|
||||
| | |-- base-fullscreen.html # Used by Authentication pages
|
||||
| | |-- base.html # Used by common pages
|
||||
| |
|
||||
| |-- accounts/ <span class="c"># Authentication pages</span>
|
||||
| |-- login.html <span class="c"># Login page</span>
|
||||
| |-- register.html <span class="c"># Registration page</span>
|
||||
| |-- accounts/ # Authentication pages
|
||||
| |-- login.html # Login page
|
||||
| |-- register.html # Registration page
|
||||
|
|
||||
|-- requirements.txt <span class="c"># Development modules - SQLite storage</span>
|
||||
|-- requirements-mysql.txt <span class="c"># Production modules - Mysql DMBS</span>
|
||||
|-- requirements-pqsql.txt <span class="c"># Production modules - PostgreSql DMBS</span>
|
||||
|-- requirements.txt # Development modules - SQLite storage
|
||||
|-- requirements-mysql.txt # Production modules - Mysql DMBS
|
||||
|-- requirements-pqsql.txt # Production modules - PostgreSql DMBS
|
||||
|
|
||||
|-- .env <span class="c"># Inject Configuration via Environment</span>
|
||||
|-- config.py <span class="c"># Set up the app</span>
|
||||
|-- run.py <span class="c"># Start the app - WSGI gateway</span>
|
||||
|-- .env # Inject Configuration via Environment
|
||||
|-- config.py # Set up the app
|
||||
|-- run.py # Start the app - WSGI gateway
|
||||
|
|
||||
|-- <span class="k">************************************************************************</span>
|
||||
</code></pre></div></div>
|
||||
|-- ************************************************************************</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1041,30 +1029,29 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
<p><strong>App / Home Blueprint</strong> structure</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>< PROJECT ROOT <span class="o">></span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><</span> <span class="nt">PROJECT</span> <span class="na">ROOT</span> <span class="nt">></span>
|
||||
|
|
||||
|-- app/
|
||||
| |-- base/ <span class="c"># Base Blueprint - handles the authentication</span>
|
||||
| |-- home/ <span class="c"># Home Blueprint - serve app pages (private area)</span>
|
||||
| |-- base/ # Base Blueprint - handles the authentication
|
||||
| |-- home/ # Home Blueprint - serve app pages (private area)
|
||||
| |
|
||||
| |-- templates/ <span class="c"># UI Kit Pages</span>
|
||||
| |-- templates/ # UI Kit Pages
|
||||
| |
|
||||
| |-- index.html <span class="c"># Default page</span>
|
||||
| |-- page-404.html <span class="c"># Error 404 - mandatory page</span>
|
||||
| |-- page-500.html <span class="c"># Error 500 - mandatory page</span>
|
||||
| |-- page-403.html <span class="c"># Error 403 - mandatory page</span>
|
||||
| |-- <span class="k">*</span>.html <span class="c"># All other HTML pages</span>
|
||||
| |-- index.html # Default page
|
||||
| |-- page-404.html # Error 404 - mandatory page
|
||||
| |-- page-500.html # Error 500 - mandatory page
|
||||
| |-- page-403.html # Error 403 - mandatory page
|
||||
| |-- *.html # All other HTML pages
|
||||
|
|
||||
|-- requirements.txt <span class="c"># Development modules - SQLite storage</span>
|
||||
|-- requirements-mysql.txt <span class="c"># Production modules - Mysql DMBS</span>
|
||||
|-- requirements-pqsql.txt <span class="c"># Production modules - PostgreSql DMBS</span>
|
||||
|-- requirements.txt # Development modules - SQLite storage
|
||||
|-- requirements-mysql.txt # Production modules - Mysql DMBS
|
||||
|-- requirements-pqsql.txt # Production modules - PostgreSql DMBS
|
||||
|
|
||||
|-- .env <span class="c"># Inject Configuration via Environment</span>
|
||||
|-- config.py <span class="c"># Set up the app</span>
|
||||
|-- run.py <span class="c"># Start the app - WSGI gateway</span>
|
||||
|-- .env # Inject Configuration via Environment
|
||||
|-- config.py # Set up the app
|
||||
|-- run.py # Start the app - WSGI gateway
|
||||
|
|
||||
|-- <span class="k">************************************************************************</span>
|
||||
</code></pre></div></div>
|
||||
|-- ************************************************************************</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1079,16 +1066,14 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
|
||||
<p>This configuration becomes active if <code class="highlighter-rouge">.env</code> file has the <code class="highlighter-rouge">DEBUG</code> file set to <em>True</em></p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Development/Debug configuration
|
||||
</span>
|
||||
<span class="c1"># Set up the App SECRET_KEY
|
||||
</span><span class="n">SECRET_KEY</span> <span class="o">=</span> <span class="n">config</span><span class="p">(</span><span class="s">'SECRET_KEY'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'S#perS3crEt_007'</span><span class="p">)</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># Development/Debug configuration
|
||||
|
||||
<span class="c1"># This will create a file in <app> FOLDER
|
||||
</span><span class="n">SQLALCHEMY_DATABASE_URI</span> <span class="o">=</span> <span class="s">'sqlite:///'</span> <span class="o">+</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">basedir</span><span class="p">,</span> <span class="s">'db.sqlite3'</span><span class="p">)</span>
|
||||
<span class="n">SQLALCHEMY_TRACK_MODIFICATIONS</span> <span class="o">=</span> <span class="bp">False</span>
|
||||
# Set up the App SECRET_KEY
|
||||
SECRET_KEY = config('SECRET_KEY', default='S#perS3crEt_007')
|
||||
|
||||
</code></pre></div></div>
|
||||
# This will create a file in <span class="nt"><app></span> FOLDER
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'db.sqlite3')
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False</code></pre></figure>
|
||||
|
||||
<p>During the first request, the SQLite database and tables are automatically created in the root in the project.</p>
|
||||
|
||||
@ -1104,23 +1089,21 @@ By default, the app will redirect guest users to the login page. To access the p
|
||||
|
||||
<p>This configuration becomes active if <code class="highlighter-rouge">.env</code> file has the <code class="highlighter-rouge">DEBUG</code> file set to <em>False</em></p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Production configuration
|
||||
</span>
|
||||
<span class="n">SESSION_COOKIE_HTTPONLY</span> <span class="o">=</span> <span class="bp">True</span>
|
||||
<span class="n">REMEMBER_COOKIE_HTTPONLY</span> <span class="o">=</span> <span class="bp">True</span>
|
||||
<span class="n">REMEMBER_COOKIE_DURATION</span> <span class="o">=</span> <span class="mi">3600</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># Production configuration
|
||||
|
||||
<span class="c1"># PostgreSQL database
|
||||
</span><span class="n">SQLALCHEMY_DATABASE_URI</span> <span class="o">=</span> <span class="s">'{}://{}:{}@{}:{}/{}'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_ENGINE'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'postgresql'</span> <span class="p">),</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_USERNAME'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'appseed'</span> <span class="p">),</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_PASS'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'pass'</span> <span class="p">),</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_HOST'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'localhost'</span> <span class="p">),</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_PORT'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">5432</span> <span class="p">),</span>
|
||||
<span class="n">config</span><span class="p">(</span> <span class="s">'DB_NAME'</span> <span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">'appseed-flask'</span> <span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
REMEMBER_COOKIE_HTTPONLY = True
|
||||
REMEMBER_COOKIE_DURATION = 3600
|
||||
|
||||
</code></pre></div></div>
|
||||
# PostgreSQL database
|
||||
SQLALCHEMY_DATABASE_URI = '{}://{}:{}@{}:{}/{}'.format(
|
||||
config( 'DB_ENGINE' , default='postgresql' ),
|
||||
config( 'DB_USERNAME' , default='appseed' ),
|
||||
config( 'DB_PASS' , default='pass' ),
|
||||
config( 'DB_HOST' , default='localhost' ),
|
||||
config( 'DB_PORT' , default=5432 ),
|
||||
config( 'DB_NAME' , default='appseed-flask' )
|
||||
)</code></pre></figure>
|
||||
|
||||
<p>In this configuration profile, the database defaults to a PostgreSQL DBMS. Make sure the <code class="highlighter-rouge">.env</code> has the right credentials to access the database.</p>
|
||||
|
||||
@ -1227,43 +1210,42 @@ The authentication status is checked by <code class="highlighter-rouge">@login_r
|
||||
<li><em>Base Blueprint</em> serve the HTML pages (index, page-404, etc) and the rest of the pages defined in the UI kit.</li>
|
||||
</ul>
|
||||
|
||||
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>< PROJECT ROOT <span class="o">></span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><</span> <span class="nt">PROJECT</span> <span class="na">ROOT</span> <span class="nt">></span>
|
||||
|
|
||||
|-- app/
|
||||
| |-- base/ <span class="c"># Base Blueprint</span>
|
||||
| |-- base/ # Base Blueprint
|
||||
| | |-- static/assets/
|
||||
| | | |-- css/ <span class="c"># UI Kit css</span>
|
||||
| | | |-- JS/ <span class="c"># Javascript files</span>
|
||||
| | | |-- images/ <span class="c"># images used by the app</span>
|
||||
| | | |-- scss/ <span class="c"># SCSS files (if any)</span>
|
||||
| | | |-- css/ # UI Kit css
|
||||
| | | |-- JS/ # Javascript files
|
||||
| | | |-- images/ # images used by the app
|
||||
| | | |-- scss/ # SCSS files (if any)
|
||||
| | |
|
||||
| | |-- templates/ <span class="c"># Templates used to render pages</span>
|
||||
| | |-- templates/ # Templates used to render pages
|
||||
| | |
|
||||
| | |-- includes/ <span class="c">#</span>
|
||||
| | | |-- navigation.html <span class="c"># Top menu component</span>
|
||||
| | | |-- sidebar.html <span class="c"># Sidebar component</span>
|
||||
| | | |-- footer.html <span class="c"># App Footer</span>
|
||||
| | | |-- scripts.html <span class="c"># Scripts common to all pages</span>
|
||||
| | |-- includes/ #
|
||||
| | | |-- navigation.html # Top menu component
|
||||
| | | |-- sidebar.html # Sidebar component
|
||||
| | | |-- footer.html # App Footer
|
||||
| | | |-- scripts.html # Scripts common to all pages
|
||||
| | |
|
||||
| | |-- layouts/ <span class="c"># Master pages</span>
|
||||
| | | |-- base-fullscreen.html <span class="c"># Used by Authentication pages</span>
|
||||
| | | |-- base.html <span class="c"># Used by common pages</span>
|
||||
| | |-- layouts/ # Master pages
|
||||
| | | |-- base-fullscreen.html # Used by Authentication pages
|
||||
| | | |-- base.html # Used by common pages
|
||||
| | |
|
||||
| | |-- accounts/ <span class="c"># Authentication pages</span>
|
||||
| | |-- login.html <span class="c"># Login page</span>
|
||||
| | |-- register.html <span class="c"># Registration page</span>
|
||||
| | |-- accounts/ # Authentication pages
|
||||
| | |-- login.html # Login page
|
||||
| | |-- register.html # Registration page
|
||||
| |
|
||||
| |-- home/ <span class="c"># Home Blueprint - serve app pages (private area)</span>
|
||||
| |-- templates/ <span class="c"># UI Kit Pages</span>
|
||||
| |-- home/ # Home Blueprint - serve app pages (private area)
|
||||
| |-- templates/ # UI Kit Pages
|
||||
| |
|
||||
| |-- index.html <span class="c"># Default page</span>
|
||||
| |-- page-404.html <span class="c"># Error 404 - mandatory page</span>
|
||||
| |-- page-500.html <span class="c"># Error 500 - mandatory page</span>
|
||||
| |-- page-403.html <span class="c"># Error 403 - mandatory page</span>
|
||||
| |-- <span class="k">*</span>.html <span class="c"># All other HTML pages</span>
|
||||
| |-- index.html # Default page
|
||||
| |-- page-404.html # Error 404 - mandatory page
|
||||
| |-- page-500.html # Error 500 - mandatory page
|
||||
| |-- page-403.html # Error 403 - mandatory page
|
||||
| |-- *.html # All other HTML pages
|
||||
|
|
||||
|-- <span class="k">************************************************************************</span>
|
||||
</code></pre></div></div>
|
||||
|-- ************************************************************************</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1286,19 +1268,17 @@ The authentication status is checked by <code class="highlighter-rouge">@login_r
|
||||
|
||||
<p><code class="highlighter-rouge">app/base/models.py</code> define the callback functions required by <strong>Flask-Login</strong> library:</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># File: app/base/models.py
|
||||
</span>
|
||||
<span class="o">@</span><span class="n">login_manager</span><span class="p">.</span><span class="n">user_loader</span>
|
||||
<span class="k">def</span> <span class="nf">user_loader</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">User</span><span class="p">.</span><span class="n">query</span><span class="p">.</span><span class="n">filter_by</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="nb">id</span><span class="p">).</span><span class="n">first</span><span class="p">()</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"># File: app/base/models.py
|
||||
|
||||
<span class="o">@</span><span class="n">login_manager</span><span class="p">.</span><span class="n">request_loader</span>
|
||||
<span class="k">def</span> <span class="nf">request_loader</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
|
||||
<span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span>
|
||||
<span class="n">user</span> <span class="o">=</span> <span class="n">User</span><span class="p">.</span><span class="n">query</span><span class="p">.</span><span class="n">filter_by</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="n">username</span><span class="p">).</span><span class="n">first</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">user</span> <span class="k">if</span> <span class="n">user</span> <span class="k">else</span> <span class="bp">None</span>
|
||||
@login_manager.user_loader
|
||||
def user_loader(id):
|
||||
return User.query.filter_by(id=id).first()
|
||||
|
||||
</code></pre></div></div>
|
||||
@login_manager.request_loader
|
||||
def request_loader(request):
|
||||
username = request.form.get('username')
|
||||
user = User.query.filter_by(username=username).first()
|
||||
return user if user else None</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1306,13 +1286,11 @@ The authentication status is checked by <code class="highlighter-rouge">@login_r
|
||||
<p><strong>Usage in contoler</strong> (Sample file)</p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
|
||||
<span class="k">def</span> <span class="nf">sample_method</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html">def sample_method(path):
|
||||
|
||||
<span class="c1"># Redirect guests users to login page
|
||||
</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">current_user</span><span class="p">.</span><span class="n">is_authenticated</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span>
|
||||
</code></pre></div></div>
|
||||
# Redirect guests users to login page
|
||||
if not current_user.is_authenticated:
|
||||
return redirect(url_for('login'))</code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
@ -1320,7 +1298,7 @@ The authentication status is checked by <code class="highlighter-rouge">@login_r
|
||||
<p><strong>Usage in view</strong></p>
|
||||
</blockquote>
|
||||
|
||||
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"collapse navbar-collapse"</span> <span class="na">id=</span><span class="s">"navigation"</span><span class="nt">></span>
|
||||
<figure class="highlight"><pre><code class="language-html" data-lang="html"> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"collapse navbar-collapse"</span> <span class="na">id=</span><span class="s">"navigation"</span><span class="nt">></span>
|
||||
<span class="nt"><ul</span> <span class="na">class=</span><span class="s">"navbar-nav ml-auto"</span><span class="nt">></span>
|
||||
|
||||
<span class="c"><!-- The Usage of <current_user> object --></span>
|
||||
@ -1342,8 +1320,7 @@ The authentication status is checked by <code class="highlighter-rouge">@login_r
|
||||
|
||||
|
||||
<span class="nt"></ul></span>
|
||||
<span class="nt"></div></span>
|
||||
</code></pre></div></div>
|
||||
<span class="nt"></div></span></code></pre></figure>
|
||||
|
||||
<p><br /></p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user