zoukankan      html  css  js  c++  java
  • flask 范例学习

    链接在此:http://dormousehole.readthedocs.org/en/latest/tutorial/introduction.html

      当然,直接根据上述链接一步一步来就可以实现所有的功能。但是,根据我在学习的过程中的心得,我觉得有必要记录一下。

      一。环境搭建

        跟前面我的记录的flask环境搭建有些不同,我在这里介绍另外一种搭建环境的方式。

        首先,从github上面下载flask。可以直接下载tar文件,或者在安装来git环境的情况下直接键入如下命令:

    git clone https://github.com/mitsuhiko/flask.git

        其次,由于flask会依赖于两个外部库,我们也如上从github上面下载:

    git clone https://github.com/mitsuhiko/jinja2.git

    git clone https://github.com/mitsuhiko/werkzeug.git

    二。目标

      我们将要创建一个博客应用。1.可以登录和注销。2.可以添加博客条目。3.页面以一定的顺序来显示。

    三。创建应用所需文件夹

    /flaskr
        /static
        /templates
        /tmp

      其中flaskr是我们应用的主文件夹,static文件夹用于存放css和js等布局文件,templates里面存放html文件,tmp文件夹存放后续生成的数据库文件。

     四。生成数据库表单

      由于我们使用的是sql数据库,所以新建一个schema.sql文件用于存放博客数据库表结构。

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

      对于sql的数据库语法虽然不是很明了,但是上述语句很容易理解。注意:上面的最后一句text后不能想当然的添加一个逗号“,”。

    五。创建应用服务器的主体

      创建flaskr.py文件,键入如下命令:

    from flask import Flask, request, session, g, redirect, url_for, \
        abort, render_template, flash
    
    #for detail
    
    
    app = Flask( __name__ )
    
    if __name__ == "__main__":
         app.run()

    此时可以在终端输入 python flaskr.py来启动服务器,然后在127.0.0.1:5000页面查看结果。由于没有视图渲染,所以会看到404 not found。

    六。创建数据库

      由于我们要将博客名称和内容存储进数据库,所以,我们先生成必要的数据库表单。

      首先,我们需要将本地的sqlite3和我们所创建的数据库结构连接起来:

    #import database
    import sqlite3
    
    #define configure data
    DATABASE = 'tmp/flaskr.db'
    
    #connect global var to app
    app.config.from_object(__name__)
    
    def connect_db():
        return sqlite3.connect( app.config['DATABASE'] )

      其次,这部分不是很理解,暂时不解释:

    from __future__ import with_statement
    from contextlib import closing
    
    def init_db():
        with closing( connect_db() ) as db:
            with app.open_resource( 'schema.sql' ) as f:
                db.cursor().executescript( f.read() )
            db.commit()

     上述完成之后,可以在python的shell环境中生成数据库表。

    >>> from flaskr import init_db
    >>> init_db()

    如果没有出现错误提示,就说明表已经被创建好了。

     七。请求数据库连接

      后续我们所发起的http请求,均与数据库有关,所以需要在请求到达的时候,和数据库进行关联。这就要靠before_request和teardown_request装饰器。

    @app.before_request
    def before_request():
        g.db = connect_db()
    
    @app.teardown_request
    def teardown_request(exception):
        g.db.close()

      这里面要注意的是g变量,这是flask的一个全局对象,它只在一个请求中起作用。所以将db保存到g中很方便。

    八。视图函数

      这回我们将要接近主题了,这个视图函数在MVC模型里面来说其实就是控制器C(controller)。我们首先看一下主页面的显示:

    @app.route('/')
    def show_entries():
        cur = g.db.execute('select title, text from entries order by id desc')
        entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
        return render_template('show_entries.html', entries=entries)

      @app.route装饰器作用是将请求路由到对应的函数,即“127.0.0.1:5000/”就对应的show_entries函数。由于刚才我们保存了与数据库的连接到g.db,所以这次我们直接使用来查询数据库。entries是根据表的内容,生成一个包含title和text对的数组。

      接下来我们直接添加视图,先来体验以下效果,在templates文件下添加layout.html文件和show_entries.html文件。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>

      注意:这里面使用的url_for可以查找到static目录下的style.css文件,如果style.css在css目录下,则static应更换为static.css。

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

       进行到这里,可以在127.0.0.1:5000页面查看效果了,但是你会发现,提示“login”等方法错误。那是因为我们还没有添加“login”方法进来。可以先预留出空间,保证我们目前的例子可以通过。添加如下代码:

    @app.route('/login', methods=['GET', 'POST'])
    def login():
        pass
    
    @app.route('/logout')
    def logout():
        pass

     ok,只要细心,到这一步,我门就算初步成功。页面没有布局(css文件未导入),而且只有login的标签(login目前还不能使用)。

      九。完善视图

      接下来我们完善视图。添加login和add视图控制函数,此时还需要添加全局变量,例如登陆密码等。

    SECRET_KEY = 'development key'
    USERNAME = 'admin'
    PASSWORD = 'default'
    @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'))
    @app.route('/add', methods=['POST'])
    def add_entry():
        if not session.get('logged_in'):
            abort(401)
        g.db.execute('insert into entries (title, text) values (?, ?)',
                     [request.form['title'], request.form['text']])
        g.db.commit()
        flash('New entry was successfully posted')
        return redirect(url_for('show_entries'))

    十。完善视图

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

    十一。添加样式表单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; }

    ok,大功告成。 

  • 相关阅读:
    [转]人生哲理小故事
    取PE文件OriginalFilename解析VERSION资源
    [转]COM对象创建外部机制
    读书的几个步骤
    zoj 2412 Farm Irrigation
    HDU 1575 Tr A
    toj 2843 Diamonds
    HDU 1856 More is better
    toj 2841 Bitwise Reverse
    hdu 1213 How Many Tables
  • 原文地址:https://www.cnblogs.com/bracken/p/2882123.html
Copyright © 2011-2022 走看看