I wrote a blog post with Django before, but it was just a quick copy. I didn’t learn much from the next chapter. Now I’ve decided to start over in flask and write down what I’ve learned every time I watch it, slow but not write a blog that asks you what you don’t know

Pycharm = pycharm = pycharm = pycharm = pycharm = pycharm

drop table if exists entries;
create table entries (
  id integer primary key autoincrement,
  title text not null.'text' text not null
);
Copy the code

Why do text have single quotes? ##Step 2: Application setup code

app = Flask(__name__) # create the application instance :)
app.config.from_object(__name__) # load config from this file , flaskr.py

# Load default config and override config from an environment variable
app.config.update(dict(
    DATABASE=os.path.join(app.root_path, 'flaskr.db'),
    SECRET_KEY='development key',
    USERNAME='admin',
    PASSWORD='default'
))
app.config.from_envvar('FLASKR_SETTINGS', silent=True)
Copy the code

Flask() is creating an application app.config.from_object and setting up where to load the configuration file from. App.config. update is setting up the configuration information, Flask will find the capitalized parameters in the configuration information to initialize, where

  • app.root_pathandos.pathThe file system is designed to accommodate different operating systems
  • secret_keyIs used to protect the session security of the client

App.config. from_envvar is used to set the configuration files that need to be loaded using environment variables. Since the configuration files are not the same during development and launch (such as DEBUG), you can set the configuration files in the shell script, run the Flask, Flaskr: PIP install *** flaskr: PIP install *** flaskr: PIP install *** PIP install *** flaskr: PIP install *** PIP install ***

/flaskr
    /flaskr
        __init__.py
        /static
        /templates
        flaskr.py
        schema.sql
    setup.py
    MANIFEST.in
Copy the code

Py, __init__.py, manifest.in setup.py

from setuptools import setup

setup(
    name='flaskr',
    packages=['flaskr'],
    include_package_data=True,
    install_requires=[
        'flask',].)Copy the code

Manifest.in specifies which files need to be included

graft flaskr/templates
graft flaskr/static
include flaskr/schema.sql
Copy the code

What the commands described in the documentation represent

The command content
include pat1 pat2 … include all files matching any of the listed patterns
exclude pat1 pat2 … exclude all files matching any of the listed patterns
recursive-include dir pat1 pat2 … include all files under dir matching any of the listed patterns
recursive-exclude dir pat1 pat2 … exclude all files under dir matching any of the listed patterns
global-include pat1 pat2 … Include all files anywhere in the Source tree matching — & any of the listed patterns
global-exclude pat1 pat2 … Exclude all files anywhere in the Source tree matching — & any of the listed patterns
prune dir exclude all files under dir
graft dir include all files under dir

init.py

from .flaskr import app
Copy the code

Operation mode

export FLASK_APP=flaskr
export FLASK_DEBUG=true
flask run
Copy the code

In Windows, set is used instead of export

# # Step 4: The database connection contains two contexts, one application context and one request context. I feel the translation of context is better, the context looks like a blank, corresponding to the two contexts have two keywords request, G for Request and Application and then the code that creates the database connection

def get_db(a):
    """Opens a new database connection if there is none yet for the current application context. """
    if not hasattr(g, 'sqlite_db'):
        g.sqlite_db = connect_db()
    return g.sqlite_db
Copy the code

Close the connection

@app.teardown_appcontext
def close_db(error):
    """Closes the database again at the end of the request."""
    if hasattr(g, 'sqlite_db'):
        g.sqlite_db.close()
Copy the code

Teardown_appcontext () is called every time the application context is destroyed. The application context is created before the request context is created and ends after the request context ends. The database is initialized by adding a hook method to the flask command line

def init_db(a):
    db = get_db()
    with app.open_resource('schema.sql', mode='r') as f:
        db.cursor().executescript(f.read())
    db.commit()

@app.cli.command('initdb')
def initdb_command(a):
    """Initializes the database."""
    init_db()
    print('Initialized the database.')
Copy the code

The app.cli.command() decorator registers a new initdb command in the flask command line, and flask automatically creates an application context when this command is executed. Open_resource () is a developer-friendly way to directly locate the resource folder in your project and start initialization

setFlask initdb Initialized the database. FLASK_APP=flaskr // Flask initdb Initialized the database.Copy the code

##Step 6: View method home view

@app.route('/')
def show_entries(a):
    db = get_db()
    cur = db.execute('select title, text from entries order by id desc')
    entries = cur.fetchall()
    return render_template('show_entries.html', entries=entries)
Copy the code

Adding a new entity

@app.route('/add', methods=['POST'])
def add_entry(a):
    if not session.get('logged_in'):
        abort(401)
    db = get_db()
    db.execute('insert into entries (title, text) values (? ,?) ',
                 [request.form['title'], request.form['text']])
    db.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))
Copy the code

Abort () sends error code to the WSGI application

flask.flash(message, Category = ‘message’) Flashes a message to the next request. In order to remove the flashed message from the session and to display it to the user, the template has to call

The implementation of the broadcast example in Android is like a log. It is written in the document that the message will be sent to the next request and redirected to the Show_entries page for login for friendly human-computer interaction

@app.route('/login', methods=['GET', 'POST'])
def login(a):
    error = None
    if request.method == 'POST':
        if request.form['username'] != app.config['USERNAME']:
            error = 'Invalid username'
        elif request.form['password'] != app.config['PASSWORD']:
            error = 'Invalid password'
        else:
            session['logged_in'] = True
            flash('You were logged in')
            return redirect(url_for('show_entries'))
    return render_template('login.html', error=error)
Copy the code

logout

@app.route('/logout')
def logout(a):
    session.pop('logged_in'.None)
    flash('You were logged out')
    return redirect(url_for('show_entries'))
Copy the code

##Step 7: Templates

layout.html


      
<title>Flaskr</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
  <h1>Flaskr</h1>
  <div class=metanav>
  {% if not session.logged_in %}
    <a href="{{ url_for('login') }}">log in</a>
  {% else %}
    <a href="{{ url_for('logout') }}">log out</a>
  {% endif %}
  </div>
  {% for message in get_flashed_messages() %}
    <div class=flash>{{ message }}</div>
  {% endfor %}
  {% block body %}{% endblock %}
</div>
Copy the code

show_entries.html

{% extends "layout.html" %}
{% block body %}
  {% if session.logged_in %}
    <form action="{{ url_for('add_entry') }}" method=post class=add-entry>
      <dl>
        <dt>Title:
        <dd><input type=text size=30 name=title>
        <dt>Text:
        <dd><textarea name=text rows=5 cols=40></textarea>
        <dd><input type=submit value=Share>
      </dl>
    </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
    <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
    <li><em>Unbelievable.  No entries here so far</em>
  {% endfor %}
  </ul>
{% endblock %}
Copy the code

login.html

{% extends "layout.html" %}
{% block body %}
  <h2>Login</h2>
  {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
  <form action="{{ url_for('login') }}" method=post>
    <dl>
      <dt>Username:
      <dd><input type=text name=username>
      <dt>Password:
      <dd><input type=password name=password>
      <dd><input type=submit value=Login>
    </dl>
  </form>
{% endblock %}
Copy the code

style.css

body            { font-family: sans-serif; background: #eee; }
a.h1.h2       { color: #377ba8; }
h1.h2          { font-family: 'Georgia', serif; margin: 0; }
h1              { border-bottom: 2px solid #eee; }
h2              { font-size: 1.2 em; }

.page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
                  padding: 0.8 em; background: white; }
.entries        { list-style: none; margin: 0; padding: 0; }
.entries li     { margin: 0.8 em 1.2 em; }
.entries li h2  { margin-left: -1em; }
.add-entry      { font-size: 0.9 em; border-bottom: 1px solid #ccc; }
.add-entry dl   { font-weight: bold; }
.metanav        { text-align: right; font-size: 0.8 em; padding: 0.3 em;
                  margin-bottom: 1em; background: #fafafa; }
.flash          { background: #cee5F5; padding: 0.5 em;
                  border: 1px solid #aacbe2; }
.error          { background: #f0d6d6; padding: 0.5 em; }
Copy the code

This pause gives you a basic idea of how flask works