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

引言

之前跟著教程用Django寫過一個博客,不過都是看著抄调衰,能運行就下一章,沒學到啥∽在澹現(xiàn)在決定重新用flask寫個嚎莉,然后每次看完都記錄學到什么,慢可以沛豌,但不能寫出了個博客問你啥你都不知道

官方文檔的入門指南

Step 0:創(chuàng)建文件

教你怎么創(chuàng)建文件趋箩,我直接用pycharm自動生成了就直接跳過

Step 1:數(shù)據(jù)庫架構

創(chuàng)建個數(shù)據(jù)庫

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()是創(chuàng)建一個應用程序
app.config.from_object設置從哪里加載配置文件
app.config.update是設置配置信息,F(xiàn)lask會找到配置信息里面大寫的參數(shù)進行初始化芍锦,其中

  • app.root_pathos.path是為了適應不同的操作系統(tǒng)的文件系統(tǒng)
  • secret_key是用來保護用戶端的session安全的

app.config.from_envvar是表示用環(huán)境變量來設置需要加載的配置文件竹勉,因為開發(fā)中和上線時需要的配置文件是不一樣的(像是DEBUG)所以可以通過在shell腳本中設置要配置的文件,在運行Flask娄琉,后面的silent的意思是如果沒有給環(huán)境變量賦值不報錯

Step 3:像安裝包一樣的安裝flaskr

里面講了為了以后可以用pip install ***的方式來安裝程序次乓,所以參照python打包指南里的方式來設計程序目錄吓歇。

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

里面新增了setup.py__init__.py票腰,MANIFEST.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

文檔里說明的命令代表的內(nèi)容

命令 內(nèi)容
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:數(shù)據(jù)庫連接

里面提到了倆個上下文(context)照瘾,一個application上下文和一個request上下文,我感覺context翻譯成語境好點丧慈,上下文看的一臉懵逼析命,對應這倆上下文有倆個關鍵字requestg來分別代表request和application
然后是創(chuàng)建數(shù)據(jù)庫連接的代碼

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 上下文摧毀時調(diào)用
application上下文是先于request上下文創(chuàng)建時創(chuàng)建逃默,后于request上下文結束時結束

Step 5:創(chuàng)建數(shù)據(jù)庫

通過在flask命令行里加入一個鉤子方法用來初始化數(shù)據(jù)庫

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命令鹃愤,當執(zhí)行這個命令后flask會自動創(chuàng)建一個application上下文,當執(zhí)行完方法里的代碼后再自己摧毀和釋放數(shù)據(jù)庫連接
open_resource()是一個方便開發(fā)者的方法完域,可以直接定位項目中的資源文件夾位置
現(xiàn)在開始執(zhí)行初始化

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()發(fā)送錯誤代碼給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里面的廣播
例子的實現(xiàn)方式是想日志一樣凹耙,就是為了友好的人機交互
文檔里寫會發(fā)送信息到下個請求和重定向到show_entries網(wǎng)頁上
登陸

@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

<!doctype 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>

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 %}

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 %}

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的基本運行方法

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市肠仪,隨后出現(xiàn)的幾起案子肖抱,更是在濱河造成了極大的恐慌,老刑警劉巖异旧,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件意述,死亡現(xiàn)場離奇詭異,居然都是意外死亡吮蛹,警方通過查閱死者的電腦和手機荤崇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潮针,“玉大人术荤,你說我怎么就攤上這事∶颗瘢” “怎么了瓣戚?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雳攘。 經(jīng)常有香客問我带兜,道長,這世上最難降的妖魔是什么吨灭? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮刑巧,結果婚禮上喧兄,老公的妹妹穿的比我還像新娘无畔。我一直安慰自己,他們只是感情好吠冤,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布浑彰。 她就那樣靜靜地躺著,像睡著了一般拯辙。 火紅的嫁衣襯著肌膚如雪郭变。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天涯保,我揣著相機與錄音诉濒,去河邊找鬼。 笑死夕春,一個胖子當著我的面吹牛未荒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播及志,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼片排,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了速侈?” 一聲冷哼從身側響起率寡,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎倚搬,沒想到半個月后勇劣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡潭枣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年比默,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盆犁。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡命咐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谐岁,到底是詐尸還是另有隱情醋奠,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布伊佃,位于F島的核電站窜司,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏航揉。R本人自食惡果不足惜塞祈,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帅涂。 院中可真熱鬧议薪,春花似錦尤蛮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哼御,卻和暖如春坯临,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恋昼。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工看靠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人焰雕。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓衷笋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親矩屁。 傳聞我的和親對象是個殘疾皇子辟宗,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個人網(wǎng)站關停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,182評論 22 257
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理吝秕,服務發(fā)現(xiàn)泊脐,斷路器,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,139評論 25 707
  • [TOC]一直想做源碼閱讀這件事烁峭,總感覺難度太高時間太少容客,可望不可見。最近正好時間充裕约郁,決定試試做一下缩挑,并記錄一下...
    何柯君閱讀 7,187評論 3 98
  • 人閑桂花落, 夜靜春山空鬓梅。 月出驚山鳥供置, 時鳴春澗中。 今天給孩子們講了這首詩绽快,人閑芥丧,夜靜,春山空坊罢,一片幽...
    嘎魚嘎魚閱讀 387評論 0 1