zoukankan      html  css  js  c++  java
  • Flask-web开发

    使用虚拟环境

    虚拟环境使用第三方实用工具virtualenv创建。输入一下命令可以检查系统是否安装了virtualenv

    virtualenv --version
    

    如果显示错误,你就需要安装这个工具。发行版

    大多数Linux发行版都提供了virtualenv包。例如,Ubantu用户可以使用下述命令安装它:

    sudo apt-gett install python-virtualenv

    如果你的电脑是Mac OS X系统,就可以使用easy_install安装virtualenv:

    sudo easy_install virtualenv
    

    如果你使用windows系统或其他没有官方virtualenv包的操作系统,那么安装程序要稍微复杂一点。

    windows安装virtuaalenv

    1.windows下载虚拟环境virtualenv

    https://bitbucket.org/pypa/setuptools
    

     

    2.找到ez_setup.py并点击下载
    3.在这个文件夹中以管理员身份执行以下命令:

    python ez_setup.py
    easy_install virtualenv
    

      

    创建虚拟环境并激活

    首先进入目标文件夹,然后执行virtualenv venv 创建虚拟环境
    激活:venvScriptsactivate
    linu和Mac OS X :source venv/bin/activate
    回到全局Python解释器:deactivate


    安装flask

    进入虚拟环境然后安装flask:pip install flask
    完整的程序

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
    return 'hello.world'
    
    if __name__ == '__main__':
    app.run(debug=True)

    flask-script支持命令行选项


    安装:pip install flask-script
    使用:

    from flask.ext.script import Manager
    app = Flask(__name__)
    manager = Manager(app)
    

     

    使用janja2模板渲染
    templates/user.html

    {% if name %}
    <h1>hello,{{ name }}</h1>
    {% else %}
    <h1>hello,world</h1>
    {% endif %}
    

      


    hello.py 

    @app.route('/')
    def index():
    return render_template('user.html')
    
    @app.route('/user/<name>')
    def user(name):
    return render_template('user.html',name=name)
    

      

    使用Bootstrap集成Twitter Bootstrap


    安装:pip install flask-bootstrap
    导入:

    from flask.ext.bootstrap import Bootstrap
    
    app = Flask(__name__)
    bootstrap = Bootstrap(app)
    

      

    templates/user.html 使用bootstrap模板:
    bootstrap中文网
    使用 BootCDN 提供的免费 CDN 加速服务(同时支持 http 和 https 协议)

    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    
    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    

      

    使用Flask-Moment本地化日期和时间


    安装:pip install flask-moment
    初始化:

    from flask_moment import Moment
    moment = Moment(app)
    

      


    html中引入moment.js

    {% block script %}
    {{ super() }}
    {{ moment.include_moment() }}
    {% endblock %}
    

      

    hello.py加入一个datatime变量

    from flask_moment import Moment
    from datetime import datetime
    
    moment = Moment(app)
    
    @app.route('/')
    def index():
    return render_template('index.html',current_time = datetime.utcnow())
    

      

    模板中渲染current_time

    <p>现在的时间是{{ moment(current_time).format('LLL') }}</p>
    <p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>


    使用表单


    安装:pip install flask_wtf
    为了保护所有表单免受跨站请求伪造,需要设置一个密钥。和设置字典一样直接赋值

    from flask_wtf import Form
    from wtforms import StringField,SubmitField
    from wtforms.validators import Required
    
    app.config['SECRET_KEY'] = 'hard to guess string'
    

     

    创建表单

    class NameForm(Form):
    name = StringField(u'你的名字')
    submit = SubmitField(u'提交')
    

      


    在视图函数中引入表单

    @app.route('/',methods=['GET','POST'])
    def index():
    form = NameForm()
    if form.validate_on_submit():
    session['name'] = form.name.data
    return redirect(url_for('index'))
    return render_template('index.html',form=form ,name=session.get('name'))
    

      


    在HTML中渲染表单

    {% import 'bootstrap/wtf.html' as wtf %}
    <form method="post">
    {{ wtf.quick_form(form) }}
    </form>
    

      

    flash消息


    导入:from flask import flash
    使用:

    flash(‘’......‘’)
    

      


    在html中渲染:

    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alert">×</button>
    {{ message }}
    </div>
    {% endfor %}
    

      

    使用Flask-SQLAlchemy管理数据库


    使用python连接mysql
    首先安装mysql-python
    linux:pip install mysql-python
    windows:链接:www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python
    点击MySQL_python-1.2.5-cp27-NONE-win32.whl下载
    pip install MySQL_python-1.2.5-cp27-NONE-win32.whl安装

    安装:pip install flask-sqlalchemy
    导入

    from flask_sqlalchemy import SQLAlchemy
    import os
    basedir = os.path.abspath(os.path.dirname(__file__))
    app.config.from_object('config')	
    db = SQLAlchemy(app)
    db.create_all()

      





    在flask-sqlalchemy中,数据库使用URL指定。最流行的数据库引擎采用的数据库URL格式如下
    数据库引擎 URL

    Mysql	mysql://username:password@hostname/database
    Postgres	postgresql://username:password@hostname/database
    SQLite(Unix)	sqlite:////absolute/path/to/database
    SQLITE(windows)	sqlite:///c:/absolute/path/to/database
    

      



    配置数据库:dialect+driver://username:password@host:port/databases
    config.py

    DIALECT = 'mysql'
    DRIVER = 'mysqldb'
    USERNAME = 'root'
    PASSWORD = ' '
    HOST = '127.0.0.1'
    PORT = '3306'
    DATABASES = 'dbdemo'
    SQLALCHEMY_DATABASE_URI=
    '{}+{}://{}:{}@{}:{}/{}?charset=utf8'.format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASES)
    SQLALCHEMY_COMMIT_ON_TEARDOWN=True
    SQLALCHEMY_TRACK_MODIFICATIONS=False
    

      

    创建表

    class Role(db.Model):
        __tablename__ = 'roles'
        id = db.Column(db.Integer,primary_key=True)
        name = db.Column(db.String(64),unique=True)
        
        users = db.relationship('User', backref='role')
        def __repr__(self):
            return '<Role %r>'%self.name
    
    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(64), unique=True ,index=True)
    
        role_id = db.Column(db.Integer,db.ForeignKey('role.id'))
        def __repr__(self):
            return '<User %r>' % self.username
    

      

    使用工厂函数:

    app/__init__.py:
    
    
    from flask import Flask,render_template,url_for,redirect,session,flash
    from flask_bootstrap import Bootstrap
    from flask_moment import Moment
    from flask_sqlalchemy import SQLAlchemy
    from config import config
    
    bootstrap = Bootstrap()
    moment = Moment()
    db = SQLAlchemy()
    
    def create_app(config_name):
        app = Flask(__name__)
        app.config.from_object(config[config_name])
        config[config_name].init_app(app)
    
        bootstrap.init_app(app)
        moment.init_app(app)
        db.init_app(app)
    
        return app    
    

    在蓝本中实现程序功能:


    app/main/__init__.py:

    from flask import Blueprint
    
    Blueprint('main',__name__)
    from . import views,errors
    

      


    app/__init__.py注册蓝本

    def create_app(config_name)
    
    
        from .main import main as main_bluprent
        app.register_blueprint(main_bluprent)
        
        return app
    

      

    使用Werkzeug实现密码散列


    app/models.py 在User模型中加入密码散列

    class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True,index=True)
    role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
    password_hash = db.Column(db.String(128))
    
    @property
    def password(self):
    raise AttributeError('password is not a readable attribute')
    
    @password.setter
    def password(self,password):
    self.password_hash = generate_password_hash(password)
    
    def verify_password(self,password):
    return check_password_hash(self.password_hash,password)

    User表的静态方法:password错误会触发AttributeError
    password_hash就是generate_password_hash生成的hash值
    verify_password需要传入password,和password_hash比较,如果正确则返回True

    在shell中测试:

    (venv) python manage.py shell

    >>> u = User()
    >>> u.password = 'cat'
    >>> u.password_hash
    'pbkdf2:sha256:50000$wBooo1Ro$b3e3d42ce34ca1e886726cc94ccecf0b274c3de913876d508837d63aabd44b1c'
    >>> u.verify_password('cat')
    True
    >>> u.verify_password('dog')
    False
    >>> u2 = User()
    >>> u2.password = 'cat'
    >>> u2.password_hash
    'pbkdf2:sha256:50000$5mLqP9WH$8f4d60676d30eb2d4c3f4b9c16e19b468998b5fd4dea6cf48611469da432f8e2'
    

      

    密码散列化测试:

    tests/test_user_models.py

    import unittest
    from app.models import User
    
    class UserModelTestCase(unittest.TestCase):
    def test_password_setter(self):
    u = User(password = 'cat')
    self.assertTrue(u.password_hash is not None)
    def test_no_password(self):
    u = User(password = 'cat')
    with self.assertRaises(AttributeError):
    u.password
    
    def test_password_verfication(self):
    u = User(password = 'cat')
    self.assertTrue(u.verify_password('cat'))
    self.assertFalse(u.verify_password('dog'))
    
    def test_password_salts_are_random(self):
    u = User(password='cat')
    u2 = User(password='cat')
    self.assertTrue(u.password_hash != u2.password_has
    

      

    创建认证蓝本


    app/auth/__init__.py

    from flask import Blueprint
    auth = Blueprint('auth',__name__)
    from . import views
    

      


    在app/__init__中注册

    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint,url_prefix='/auth')
    
    
    

      

    app/auth/views.py
    from flask import render_template
    from . import auth
    
    
    @auth.route('/login')
    def login():
    return render_template('auth/login.html')
    

      

    使用Flask-login认证用户


    *安装:pip install flask-login


    准备用于登录的用户模型

    Flask-Login要求实现的用户方法

    *方法 说明
    is_authenticated 如果用户已经登录,必须返回True,否则返回False
    is_active 如果允许用户登录,必须返回True,否则返回False。如果要禁用用户,可以返回False
    is_anonymous 对普通用户必须返回False
    get_id 必须返回用户的唯一标识符,使用unicode编码字符串

    *flask—login提供了一个UserMixin类,其中包含这些方法的默认实现,需要在数据库中继承

    *初始化:
    app/__init__.py:

    from flask_login import LoginManager
    
    login_manager = LoginManager()
    login_manager.session_protection='strong'
    login_manager.login_view = 'auth.login'
    

      


    login_manager.session_protection属性可以设为None,‘basic’或‘strong’,以提供不同的安全等级防止用户会话遭篡改
    设为strong时,会记录客户端IP地址和浏览器的用户代理信息,如果发现异动就登出用户。
    login_view属性设置登录页面的端点

    *最后,Flask_login要求程序实现一个回调函数,使用指定的标识符加载用户。
    app/models.py

    from . import login_manager
    
    @login_manager.user_loader()
    def load_user(user_id):
    return User.query.get(int(user_id))
    

      


    加载用户的回调函数接收Unicode字符串形式表示的用户标识符。如果能找到用户,这个函数必须返回用户对象;否则应该返回None

    *保护路由


    为了保护路由只让认证用户访问,Flask-login提供了一个login_required修饰器,未认证的用户访问这个路由,会拦截请求把用户发往登录页面

    from flask_login import login_required
    
    @app.route('/secret')
    @login_required
    def secret():
    return 'Only authenticated users are allowed'
    

     打开URL

    manage.py

    @manager.command
    def dev():
        from livereload import Server
        live_server = Server(app.wsgi_app)
        live_server.watch('**/*.*')
        live_server.serve(open_url = True)
    

      

  • 相关阅读:
    爬虫第二弹之http协议和https协议
    爬虫第一弹之py爬虫的相关概念
    Flask第十四篇- Flask-Session组件、WTForms组件、数据库连接池(POOL)
    Flask第十三篇- flask请求上下文源码解读、http聊天室单聊/群聊(基于gevent-websocket)
    Flask第十二篇- flask中的CBV、werkzeug+上下文初步解读、偏函数和线程安全
    Flask第十一篇装饰器的坑及解决办法、flask中的路由/实例化配置/对象配置/蓝图/特殊装饰器(中间件、重定义错误页面)
    Flask第十八篇 Flask-Migrate
    Flask第十七篇 Flask-Scrip
    Flask第十六篇 Flask-SQLAlchemy
    Flask第十篇 before_request after_request
  • 原文地址:https://www.cnblogs.com/liushaocong/p/7225139.html
Copyright © 2011-2022 走看看