我的个人博客搭建日志------Flask篇之官方教程

引言

之前跟着教程用Django写过一个博客,不过都是看着抄,能运行就下一章,没学到啥。现在决定重新用flask写个,然后每次看完都记录学到什么,慢可以,但不能写出了个博客问你啥你都不知道

官方文档的入门指南

Step 0:创建文件

教你怎么创建文件,我直接用pycharm自动生成了就直接跳过

Step 1:数据库架构

创建个数据库

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

其他都懂,为啥text要有单引号?

Step 2:应用程序设置代码

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)

整个设置程序,指南里说最好的办法是把这些配置信息一起写到一个.ini或者.py的文件里
Flask()是创建一个应用程序
app.config.from_object设置从哪里加载配置文件
app.config.update是设置配置信息,Flask会找到配置信息里面大写的参数进行初始化,其中

  • app.root_pathos.path是为了适应不同的操作系统的文件系统
  • secret_key是用来保护用户端的session安全的

app.config.from_envvar是表示用环境变量来设置需要加载的配置文件,因为开发中和上线时需要的配置文件是不一样的(像是DEBUG)所以可以通过在shell脚本中设置要配置的文件,在运行Flask,后面的silent的意思是如果没有给环境变量赋值不报错

Step 3:像安装包一样的安装flaskr

里面讲了为了以后可以用pip install ***的方式来安装程序,所以参照python打包指南里的方式来设计程序目录。

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

里面新增了setup.py__init__.pyMANIFEST.in
setup.py

from setuptools import setup

setup(
    name='flaskr',
    packages=['flaskr'],
    include_package_data=True,
    install_requires=[
        'flask',
    ],
)

MANIFEST.in
指定那些文件需要被包含

graft flaskr/templates
graft flaskr/static
include flaskr/schema.sql

文档里说明的命令代表的内容

命令 内容
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

运行方式

export FLASK_APP=flaskr
export FLASK_DEBUG=true
flask run

windows下用set来代替export

Step 4:数据库连接

里面提到了俩个上下文(context),一个application上下文和一个request上下文,我感觉context翻译成语境好点,上下文看的一脸懵逼,对应这俩上下文有俩个关键字requestg来分别代表request和application
然后是创建数据库连接的代码

def get_db():
    """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

关闭连接

@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()

teardown_appcontext()会在每次application 上下文摧毁时调用
application上下文是先于request上下文创建时创建,后于request上下文结束时结束

Step 5:创建数据库

通过在flask命令行里加入一个钩子方法用来初始化数据库

def init_db():
    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():
    """Initializes the database."""
    init_db()
    print('Initialized the database.')

app.cli.command()装饰器会在flask命令行里注册一个新的initdb命令,当执行这个命令后flask会自动创建一个application上下文,当执行完方法里的代码后再自己摧毁和释放数据库连接
open_resource()是一个方便开发者的方法,可以直接定位项目中的资源文件夹位置
现在开始执行初始化

set FLASK_APP=flaskr  //这里文档里没写所以运行时会提示没有该命令
flask initdb
Initialized the database.

Step 6:视图方法

主页视图

@app.route('/')
def show_entries():
    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)

添加新实体

@app.route('/add', methods=['POST'])
def add_entry():
    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'))

abort()发送错误代码给WSGI应用

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

不太懂,说是闪烁消息,感觉想Android里面的toast,但是感觉又是Android里面的广播
例子的实现方式是想日志一样,就是为了友好的人机交互
文档里写会发送信息到下个请求和重定向到show_entries网页上
登陆

@app.route('/login', methods=['GET', 'POST'])
def login():
    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)

登出

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

Step 7:模板

layout.html


Flaskr

Flaskr

{% if not session.logged_in %} log in {% else %} log out {% endif %}
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %} {% block body %}{% endblock %}

show_entries.html

{% extends "layout.html" %}
{% block body %}
  {% if session.logged_in %}
    
Title:
Text:
{% endif %}
    {% for entry in entries %}
  • {{ entry.title }}

    {{ entry.text|safe }} {% else %}
  • Unbelievable. No entries here so far {% endfor %}
{% endblock %}

login.html

{% extends "layout.html" %}
{% block body %}
  

Login

{% if error %}

Error: {{ error }}{% endif %}

Username:
Password:
{% endblock %}

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.2em; }

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

在这停顿

大概了解到了整个flask的基本运行方法

你可能感兴趣的:(我的个人博客搭建日志------Flask篇之官方教程)