flask开发笔记

更新ing
不适合新手入门,适合写项目时参考备忘

虚拟环境

  • 安装虚拟环境
    pip install virtualenv
  • 新建环境
    virtualenv [name]
  • 激活环境
    在进入虚拟环境目录下Scripts文件夹后
    activate
  • 退出环境
    在进入虚拟环境目录下Scripts文件夹后
    deactivate

Debug模式

  • 开启
    app.run(debug=Ture)
  • 关闭
    app.run(debug=False)

配置文件

新建一个config.py

##encoding utf-8

DEBUG = Ture

然后在主程序里面导入

import config

最后应用

app.config.from_object(config)

url传入参数

@app.route('/article/<id>')
def article(id):
  return u"%s" % id

url反转

from flask import url_for
##
url_for("article", id="123")
## return /article/123

重定义向

from flask import redirect
##
return redirect(url_for("login"))
return redirect("/login")

模板

创建

template文件下新建一个index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Hello, {{ name }}</h1>
    <p>e-mail:{{ email }}</p>
</body>
</html>
##encoding: utf-8

from flask import Flask, render_template
import config

app = Flask(__name__)
app.config.from_object(config)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/user/<name>/<email>')
def name(name,email):
    context={
        'name':name,
        'email':email
    }
    return render_template('index.html', **context)
    ## = return render_template('index.html', name=name, email=email)

if __name__ == '__main__':
    app.run()

jinjia2语法

模板继承

{% extends 'base.html' %}

{% block main %}
{{ super() }}
{% endblock %}

flash

配合模板使用
使用了bootstrap样式

{% with messages = get_flashed_messages() %}
    {% if messages %}
    {% for message in messages %}
        <div class="alert alert-warning">
            <button type="button" class="close" data-dismiss="alert"> &times;</button>
            {{ message }}
        </div>
    {% endfor %}
    {% endif %}
{% endwith %}

flash(u"Message")提示信息

flash("Hello world!")

加载静态文件

url_for('static', filename='css/base.css')

MySQL数据库命令

进入MySQL 5.7 Command Line Client - Unicode输入密码后

  • 创建
    create database [databaseName] charset utf8;

    若想支持emoji😃,则需将utf8换为utf8mb4(当然flask的config.py也要改)

  • 切换数据库
    use [databaseName]

  • 查看
    show tables
    desc [tableName]
    select * from [tableName]

  • 删除
    delete from [tableName] 删除表数据

    delete from user where id=3; 删除制定id的数据

数据库

配置

config.py

DIALECT = 'mysql'
DRIVER = 'mysqldb'
USERNAME = 'root'
PASSWORD = 'root'
HOST = '127.0.0.1'
PORT = '3306'
DATABASE = 'db_demo1'

SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False

更新、提交、删除

  • 提交
    db.session.commit()

  • 添加
    db.session.add()

  • 删除
    db.session.delete()

  • 创建数据库(更新表)

    from models import User,Question # 要import所有的表模型
    db.create_all()
    
  • 删除所有数据
    db.drop_all()

模型操作

创建模型

class User(db.Model):
    __tablename__='user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) #autoincrement自增长
    username = db.Column(db.String(100), nullable=False)
    pw = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), nullable=False, unique=True) #unique独一无二

    def __repr__(self): //定义输出格式 print
        return '<User %r>' % self.username

关联表、反向引用

class Question(db.Model):
    ##...
    ## 将Quseion模型中的author_id与User模型的id相关联绑定
    ## 注意,user是表名(即__tablename__),而不是模型类名
    author_id = db.Colum(db.Integer, db.ForeignKey('user.id'))
    ## 将当前模型加入到User模型中,Question.author访问到对应的User模型,User.questions访问到所有的Question模型
    ## 注意,User是类名,而不是表名(与上面的相反)
    author = db.relationship('User', backref=db.backref('questions'))

查询

参考于玩转MySQL golden's 文档笔记入门教程没有告诉你的sqlalchemy常用操作

  • 查询表中全部数据

    # 注意,此处的查询结果完全取决于代码示例中的
    # def __repr__(self)
    python
    >>> from hello import db,Role,User
    >>> Role.query.all()
    [<Role u'Administrator'>, <Role u'User'>]
    >>> User.query.all()
    [<User u'john',Role id 1L>, <User u'susan',Role id 3L>, <User u'david',Role id 3L>]
    按照一个条件过滤数据记录(where)
    
    >>> from hello import db,Role,User
    >>> Role.query.filter_by(name='Administrator').first()
    <Role u'Administrator'>
    >>> User.query.filter_by(role_id=3).all()
    [<User u'susan',Role id 3L>, <User u'david',Role id 3L>]
    >>> User.query.filter_by(role_id=3).first()
    <User u'susan',Role id 3L>
    按照两个条件过滤数据记录(where and)
    
    >>> from hello import db,Role,User
    >>> User.query.filter_by(role_id=3,username='susan').first()
    <User u'susan',Role id 3L>
    >>> User.query.filter_by(role_id=3,username='susan').all()
    [<User u'susan',Role id 3L>]
    
  • 聚合(count)

    >>> from hello import db,Role,User
    >>> User.query.filter_by(role_id=3,username='susan').count()
    1L
    >>> User.query.filter_by(role_id=3).count()
    2L
    >>> User.query.count()
    3L
    
  • 求和(sum)

    >>> from hello import db,Role,User
    >>> from sqlalchemy.sql import func
    >>> User.query.with_entities(func.sum(User.id)).all()
    [(Decimal('6'),)]
    >>> User.query.with_entities(func.sum(User.role_id)).all()
    [(Decimal('7'),)]
    
  • 平均数(avg)

    >>> from hello import db,Role,User
    >>> from sqlalchemy.sql import func
    >>> User.query.with_entities(func.avg(User.role_id)).all()
    [(Decimal('2.3333'),)]
    >>> User.query.with_entities(func.avg(User.id)).all()
    [(Decimal('2.0000'),)]
    
  • 排序(order by)

    >>> from hello import db,Role,User
    # 升序(asc)
    >>> User.query.order_by(User.role_id).all()
    [<User u'john',Role id 1L>, <User u'susan',Role id 3L>, <User u'david',Role id 3L>]
    # 降序(desc)
    >>> User.query.order_by(User.role_id.desc()).all()
    [<User u'susan',Role id 3L>, <User u'david',Role id 3L>, <User u'john',Role id 1L>]
    
  • 分组(group by)

    >>> from hello import db,Role,User
    >>> User.query.group_by(User.role_id).all()
    [<User u'john',Role id 1L>, <User u'susan',Role id 3L>]
    
  • 限制(limit)

    >>> from hello import db,Role,User
    >>> User.query.all()
    [<User u'john',Role id 1L>, <User u'susan',Role id 3L>, <User u'david',Role id 3L>]
    # limit 1
    >>> User.query.limit(1).all()
    [<User u'john',Role id 1L>]
    # limit 2,1
    >>> User.query.limit(1).offset(2).all()
    [<User u'david',Role id 3L>]
    >>> User.query.filter_by(role_id=3).all()
    [<User u'susan',Role id 3L>, <User u'david',Role id 3L>]
    # limit 1
    >>> User.query.filter_by(role_id=3).limit(1).all()
    [<User u'susan',Role id 3L>]
    # limit 1,1
    >>> User.query.filter_by(role_id=3).limit(1).offset(1).all()
    [<User u'david',Role id 3L>]
    
  • join

    多表合并查询,详见

    session.query(User).join(Address).\
    filter(Address.email_address=='jack@google.com').all()
    

分页

数据库Models定义

  • 关联模型

    ## 外键定义
    auther_id = db.Column(dp.Integer, db.ForeignKey('user.id'))
    ## 互相引用
    auther = db.relationship('User', backref=db.backref('questions'))
    

python装饰器

*args,**kwargs可以代表任何形式的形参

from functools import wraps
##...
def my_decorator(func):

  @wraps(func)
  def wrapper(*args,**kwargs):
    ##do something
    func(*args,**kwargs)
  return wrapper
##...
@my_decorator
def run():
  pass

蓝图

目的:为了使业务逻辑更加清晰

项目结构:

├── project
│   ├── app ## 业务目录
│   │   ├── auto
│   │   │   └── views.py
│   │   └── main
│   │       └── views.py
│   ├── main.py ## 入口程序

app.main.views.py

from flask import Flask, Blueprint

main = Blueprint('main',__name__)

@main.route('/')
def index():
    return 'Main'

app.auto.views.py

from flask import Flask, Blueprint

auto = Blueprint('auto',__name__)

@auto.route('/')
def login():
    return 'Auto'

main.py

from flask import Flask
from app.main.views import *
from app.auto.views import *
app = Flask(__name__)
app.register_blueprint(main) ## 挂载蓝图main
app.register_blueprint(auto,url_prefix='/auto') ## 挂载蓝图auto,并指定访问前缀

if __name__ == '__main__':
    app.run()

于是访问/时,显示Main,而访问/auto/,显示Auto

  • 注意

    url_for('main.index') ## 需要指定蓝图,如main
    url_for('.index') ## 可以缺省相对定位
    
    ## 静态文件 URL 是 /admin/static 
    admin = Blueprint('admin', __name__, static_folder='static')
    
    ## 真正的模板文件为 yourapplication/admin/templates/admin/index.html
    admin = Blueprint('admin', __name__, template_folder='templates')
    
posted @ 2018-11-17 23:09  Santiego  阅读(218)  评论(0编辑  收藏  举报