python之Flask

Python虚拟环境

  1. python虚拟环境是为了解决电脑上存在一个框架的多个版本,使用虚拟环境解决这个问题

  2. 通过pip命令安装虚拟环境:

pip3 install virtualenv
  1. 开辟新的虚拟环境:
/** [virtualenv-name] */ 是盒子的名字
virtualenv  [virtualenv-name] 
  1. 激活虚拟环境
    • mac下激活虚拟环境命令: source ~/Virtualenv/flask-env/bin/activate
    • 退出虚拟环境 deactivate

安装flask框架

  1. 需要在虚拟环境中安装flask框架
(flask-env) Liu:flask-env liuzhanjun$ pip3 install flask
  1. 查看flask是否安装成功

Flask

  1. flask入口详解
#encoding: utf-8

from flask import Flask

app = Flask(__name__)

# @app.route 是一个装饰器
# @开头,并且在函数的上面,说明是装饰器
# 这个装饰器的左右, 是做一个url与试图函数的映射
@app.route('/My_name/<string:name>')
def My_name(name):
    return 'My name is: {}'.format(name)

# 入口程序
if __name__ == '__main__':
    # 类似While True:一样一直在监听
    # 可以填写参数, 接收用户信息的请求
    app.run()
  1. 设置debug模式:
  1. 在app.run()中传入一个关键字参数debug, app.run(debug=True),就设置了当前项目为debug模式
    2.debug模式的两大功能:
  • 当程序出现问题的时候, 可以在页面中看到错误信息和出错的位置。
  • 只要修改了项目中的python文件,不需要手动重新启动服务器。
  1. 设置配置文件

1.新建一个configLogic.py文件
2.在住app文件到导入这个文件, 并且配置到app中, 示例代码如下:

import configLogic
app.config.from_object(configLogic)

3.还有许多的其他参数, 都是放置在这个配置文件中的,比如SECRET_KEYSQLALCHEMY这些配置,都是在这个文件中的

  1. URL参数

1.参数的作用: 可以在相同的URL,但是置顶不同的参宿, 来加载不同的数据。
2.在flask中如何使用参数:

#  参数需要写在 `<>` 中
#  视图函数中需要放和url参数同名的参数
@app.route('/My_name/<string:name>')
def My_name(name):
    return 'My name is: {}'.format(name)
  1. 反转url
  1. 什么叫做反转URL: 从视图函数到url的转换叫做反转URL
  2. 反转url的用处:

2.1在页面重定向的时候,会使用url反转
2.2在模板中,也会使用url反转

页面跳转和重定向

1.用处: 在用户访问一些需要登录的页面的时候,如果用户没有登录, 那么可以让它重定向到登录页面
2.代码实现:

#encoding: utf-8

from flask import Flask,redirect,url_for

app = Flask(__name__)


@app.route('/')
def hello_world():
    # 使用url_for进行反转的话, 不论@app.route('/login/')中的/login/怎么改变,都不会印象到反转的结果
    # 使用url进行反转时, url_for('接口函数名'),直接调用接口函数, 防止接口中参数改变影响请求结果
    # login_url = url_for('login')
    # return redirect(login_url)
    return u'这是首页'

@app.route('/login/')
def login():
    return '这是登录页面'

@app.route('/requestion/<is_login>')
def requestion(is_login):
    if is_login == '1' :
        return '这是问答页面'
    else:
        # 根据用户传来的参数重定向到login登录页面, 里边使用是url反转
        return redirect(url_for('login'))

# 入口程序
if __name__ == '__main__':
    app.run(debug=True, host='127.0.0.1',port=8080)
  1. Flask渲染Jinja2模板和传值
  1. 如何渲染模板:
  • 模板放在templates文件夹下
  • flask中导入render_template函数
  • 在视图函数中,使用render_template函数,渲染模板,注意:只需要填写模板的名字,不需要填写templates这个文件夹的路径。

2.模板传参:

  • 如果只有一个或者少量参数,直接在render_template函数中添加关键字参数就可以了
  • 如果有多个参数的时候, 那么可以先把所有的参数放到字典中, 然后在render_template中,使用两个星号**,把字典转换成关键字参数传递进去, 这样的代码更方便管理和使用。

3.在模板中, 如果要使用一个变量, 语法是{{ parms }}
4.访问模型中的属性或者是字典,可以通过{{params.property}}的形式, 或者是使用{{params[‘age’]}}, 示例代码:

# 1.接口中定义好需要调用的模型Person类
@app.route('/')
def index():

    class Person(object):
        name = u'刘战军'
        age = 25

    p = Person()

    context = {'username':'刘战军',
               'age':18, 'sex':'男',
               'friend': '王磊',
               'person': p,
               'websties': {
                   'baidu': 'www.baidu.com',
                   'google': 'www.google.com'
               }
               }

    return render_template('index.html', **context)
# 2.模板中调用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    这是HTML种出现的文字
    <p>姓名: {{ username }}</p>
    <p>性别: {{ sex }}</p>
    <p>年龄: {{ age }}</p>
    <p>朋友: {{ friend }}</p>

    <hr>
    <p>名字: {{ person.name }}</p>
    <p>名字: {{ person.age }}</p>

    <hr>
    <p>名字: {{ websties.baidu }}</p>
    <p>名字: {{ websties.google }}</p>

</body>
</html>
  1. if判断

1.语法:

    {% if userInfo %}
        <a href="#">{{userInfo.username}}</a>
        <a href="#">注销</a>
    {% else %}
        <a href="#">登录</a>
        <a href="#">注册</a>
    {% endif %}

2.if的使用, 可以和python中相差无几
3.在模板中使用if语句的时候注意

#encoding: utf-8

from flask import Flask,render_template

app = Flask(__name__)


@app.route('/<is_login>/')
def index(is_login):
    # 用户使用传值也需要注意, 这里的`1`的类型
    if is_login == '1' :
        print('登录状态')
        userInfo = {
            'username': '刘战军',
            'age': 18
        }
        websites = ['www.baidu.com', 'www.google.com']
        return render_template('index_for.html', userInfo=userInfo, websites=websites) # 注意: 模板中需要获取当前这个信息的话,必须使用这种方式传值
    else :
        print('未登录状态')
        return render_template('if_statement.html')

# 入口程序
if __name__ == '__main__':
    app.run(debug=True, host='127.0.0.1',port=8081)
  1. for 的使用
  1. 字典的遍历, 语法和python一样, 可以使用items()keys()values()iteritems()iterkeys()itrervalues()
    {% for k,v in userInfo.items() %}
        <p>{{ k }} : {{ v }}</p>
    {% endfor %}

2.列表的遍历: 语法和python一样

    {% for website in websites %}
        <p>{{ website }}</p>
    {% endfor %}
  1. 过滤器

过滤的对象是模板中的变量

  1. 语法:
  • 介绍: 过滤器可以处理变量, 把原始的变量经过处理后再展示出来。 作用的对象是变量。
  • 语法:
default过滤器
{{ avatar|default('xxxxx') }}

2.default过滤器: 如果当前的变量不存在,这时候可以指定默认值。
3.len过滤器:作为求列表、字符串、字典、元组的长度。

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
<!--这里使用的是default()过滤器,可以作为placeholder使用-->
<img src="{{ avatar|default('http://upload.jianshu.io/users/upload_avatars/2542851/0dca220dd6bb.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64') }}" alt="">

<hr>
<!--这里使用的是length过滤器,可以作为求列表、字符串、字典、元组的长度-->
<p>评论数: ({{ coments| length }})</p>
<ul>
   {% for coment in coments %}
       <li>
           <a href="#">{{ coment.user }}</a>
           <p>{{ coment.content }}</p>
       </li>

   {% endfor %}
</ul>

</body>
</html>
  1. 继承和block

1.集成的作用和语法:

  • 作用:可以吧一些公共的代码都放在父模板中,避免每个模板写同样的代码。
  • 代码:{% extends 'index_base.html' %}
  1. block实现:
  • 作用:可以让子模板实现一些自己的需求,父模板需要提前定义好。
  • 注意点:子模板中的代码, 不许放在block块中。
  1. url链接

使用url_for(试图函数名称)可以翻转成url

#encoding: utf-8

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index_url.html')

@app.route('/login/')
def login():
    return render_template('index_login.html')


# 入口程序
if __name__ == '__main__':
    app.run(debug=True,host='127.0.0.1',port=8081)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="{{ url_for('login') }}" id="">登录</a>
</body>
</html>
  1. 加载静态文件

1.语法:url_for('static',filename='路径')
2.静态文件,flask会从static文件夹中开始寻找,所以不需要再写static这个路径了。
3.可以加载css文件,可以加载js文件,还有images资源等文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{{  url_for('static',filename='css/index.css') }}">
    <script src="{{ url_for('static',filename='js/index.js') }}"></script>
</head>
<body>
    <a href="{{ url_for('login') }}">登录</a>
    <img src="{{ url_for('static',filename='images/gonggao.png') }}" alt="">
</body>
</html>
静态文件加载路径示意图.png




SQLAIchemy数据库
  1. mysql mac安装只需要到mysql官网下载进行安装, 安装步骤,这里不赘述, 百度一大堆

  2. Flask-SQLAlchemy介绍与安装:

  1. ORM: Object Relationship Mapping(模型关系映射)
  1. flask-sqlalchemy是一套ORM框架

3.ORM的好处:可以让我们操作数据库跟操作对象一样,非常方便。因为一个表就抽象成一个类, 一条数据就抽象成该类的一个对象。

4.安装flask-sqlalchemy : sudo pip3 install flask-sqlalchemy

  1. Flask-SQLAlchemy的使用:
  1. 初始化和设置数据库配置信息:
    设置配置信息: 在config.py文件中添加一下配置信息:
  # encoding: utf-8

  # dialect+driver:/username:password@host:prot/database

  DIALECT = 'mysql'
  DRIVER = 'mysqldb'
  USERNAME = 'root'
  PASSWORD = 'root'
  HOST = '127.0.0.1'
  PORT = '3306' # mysql自带端口号
  DATABASE = 

2.没有DATABASE需要创建一个

Last login: Sun Nov 19 17:10:14 on ttys002

# 打开数据库
Liu:~ liuzhanjun$ mysql -uroot -p
Enter password:  # 输入密码
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 498
Server version: 5.7.20 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

# 创建db_demoFrist指令:create database db_demoFrist charset utf8;
mysql> create database db_demoFrist charset utf8;
Query OK, 1 row affected (0.01 sec)

mysql> 

3.初始化和设置数据库配置信息:

  • 使用flask——sqlalchemy中的SQLAlchemy进行初始化:

from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 链接数据库配置信息
app.config.from_object(config)
# 初始化SQLAlchemy对象
db = SQLAlchemy(app)

4.在主app文件中, 添加配置文件:

import config
app = Flask(__name__)

# 链接数据库配置信息 (暂时不会使用添加其他config配置文件方式)
# app.config.from_object(config)

# 这里登陆的是root用户,要填上自己的密码,MySQL的默认端口是3306,填上之前创建的数据库名jianshu,连接方式参考 \
app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:root@127.0.0.1:3306/db_demo6'
#设置这一项是每次请求结束后都会自动提交数据库中的变动
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True

# 初始化SQLAlchemy对象
db = SQLAlchemy(app)

5.做测试,看有没有问题:

# 测试数据库用户名密码是否正确
db.create_all()

如果没有报错, 说明配置信息没有问题, 如果报错, 根据错误进行更改
使用Flask-SQLAlchemy创建模型与表的映射:
  1. 模型需要继承自db.Model, 然后需要映射到表中的属性,必须写成db.Column的数据类型。参考如下图
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config

app = Flask(__name__)

# 链接数据库配置信息(暂时不会使用配置文件方式进行配置数据库信息)
# app.config.from_object(config)

# 这里登陆的是root用户,要填上自己的密码,MySQL的默认端口是3306,填上之前创建的数据库名jianshu,连接方式参考 \
app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:root@127.0.0.1:3306/db_demo6'
#设置这一项是每次请求结束后都会自动提交数据库中的变动
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True

# 初始化SQLAlchemy对象
db = SQLAlchemy(app)

# # 测试数据库用户名密码是否正确
# db.create_all()

# creat table article (
#     id int primary key autoincrement, # 自增长的一个之, primary 作为主键使用
#     title varchar(100) not null,      # 最长字符为100, 并且不能为空
#     content text not null
# )

class Article(db.Model):
    
    # 定义表名
    __tablename__ = 'article'
    # 定义列对象
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    
    # repr()方法显示一个可读字符串,虽然不是完全必要,不过用于调试和测试还是很不错的。
    # def __repr__(self):
    #     return '<Article {}> '.format(self.title)


# 映射到数据库中 `这个方法只会映射到数据库一次,再次创建新的数据不会进行存储`6
db.create_all()

@app.route('/')
def index():
    return 'index'


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

查询数据库指令以及查询时常见的问题

打开库: 
use 数据库名;

1. 查询数据库表:
show tables;
例如:
mysql> show tables;

2. 查询数据表内容:
desc 表名;
例如:
mysql> desc article;

常见问题:  在打开数据库时提示重新设置密码的问题
1820 (HY000): You must reset your password using ALTER USER statement before executing this statement
解决方式:
mysql> SET PASSWORD = PASSWORD('root这里需要输入新密码');
  1. 数据类型:


    数据参数类型.jpeg
  2. 其他参数:

    • primary_key : 代表的是将这个字段设置为主键
    • autoincrement : 代表的是这个主键为自增长的。
    • nullable : 代表的是这个字段是否可以为空,默认可以为空。可以将这个值设置为False, 在数据库中,这个值就不能为空了。
    • 最后需要调用db.create_all来将模型真正的创建到数据库中。
Flask-SQLAlchemy 数据的增、删、改、查;

数据的增删改查都是db的session来进行操作;
不论做增删改查操作都需要进行事务的处理db.session.commit()来操作;

  1. 增:
@app.route('/')
def hello_world():
    # 增加数据
    article1 = Article(title='aaa',content='bbb')
    db.session.add(article1)
    # 存储数据
    db.session.commit()
    return 'Hello World!'
  1. 查:
* 查询:
article1 = Article.query.filter(Article.title == 'aaa')
print('article1 = {}'.format(article1))

* 结果:
article1 = SELECT article.id AS article_id, article.title AS article_title, article.content AS article_content 
FROM article 
WHERE article.title = %(title_1)s


* 查询: 
article1 = Article.query.filter(Article.title == 'aaa').first()
print('article1 = {}'.format(article1))
print('title = {}'.format(article1.title))
print('content = {}'.format(article1.content))

* 结果:
article1 = <Article 1>
title = aaa
content = bbb
  1. 改:
    # 3.1 先把你需要更改的数据查找出来
    article1 = Article.query.filter(Article.title == 'aaa').first()
    # 3.2 把这条数据, 你需要修改的地方进行修改
    article1.title = 'news title'
    # 3.3 做事务的提交
    db.session.commit()
  1. 删:
    # 4.1 先把你需要删除的数据查找出来
    article1 = Article.query.filter(Article.content == 'bbb').first()
    # 4.2 删除数据
    db.session.delete(article1)
    # 4.3 做事务提交
    db.session.commit()
Flask-SQLAlchemy外键及其关系:
  1. 外键:
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(100), nullable=False)

class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    # 如果要使用【外键】进行链表查询, db.Column中第一个参数必须和需要链接的另一个字段类型保持一致,第二个参数是使用db.ForeignKey()函数进行表名加字段的链接
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  1. author = db.relationship('User', backref = db.backref('articles'))解释:
    • Article这个模型添加一个author属性, 可以访问这篇文章的作者的数据, 像访问普通模型一样。
    • backref是定义反向引用, 可以通过User访问这个模型写的所有文章。
class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    # 如果要进行链表查询, db.Column中第一个参数必须和需要链接的另一个字段类型保持一致,第二个参数是使用db.ForeignKey()函数进行表名加字段的链接
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    # 添加author属性, 通过relationship这种方式可以直接访问User模型中的属性。
    author = db.relationship('User', backref = db.backref('articles'))
@app.route('/')
def index():

    # user = User(username = 'liuzhanjun')
    # db.session.add(user)
    # db.session.commit()

    # article = Article(title = 'shuihu', content = 'shuihuzhuan')
    # article.author = User.query.filter(User.id == 1).first()
    # db.session.add(article)
    # db.session.commit()


    # 根据标题为sanguo的找作者是的名字
    # article = Article.query.filter(Article.title == 'sanguo').first()
    # print('username: {}'.format(article.author.username))

    # 根据作者,查找作者写的所有文章
    user = User.query.filter(User.username == 'liuzhanjun').first()
    result = user.articles
    for article in result:
        print('-'*10)
        print(article.title)
        
    return 'index'
  1. 前面是一对多的关系, 多对多关系如下:
  • 1.多对多的关系要通过一个中间表进行关联。
  • 2.中间表, 不能通过class的方式实现, 只能通过db.Table的方式实现。
  • 3.设置关联:
article_tag = db.Table('article_tag',

                db.Column('article_id', db.Integer, db.ForeignKey('article.id'), primary_key=True),
                db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True)
                    )

class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    # 第一个参数是需要关联的模型名称, 第二参数为链接的模型名称(桥接), 第三个参数是方向参照
    tags = db.relationship('Tag', secondary = article_tag, backref = db.backref('tags'))

class Tag(db.Model):
    __tablename__ = 'tag'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100), nullable=False)

注意: 需要使用一个关键字参数secondary = 中间表来进行关联。

    1. 访问和数据添加可以通过以下方式进行操作:
      • 添加数据
    article1 = Article(title = "honglou")
    article2 = Article(title="xiyou")

    tag1 = Tag(name = "link-honglou")
    tag2 = Tag(name="link-xiyou")

    db.session.add(article1)
    db.session.add(article2)
    db.session.add(tag1)
    db.session.add(tag2)

    article1.tags.append(tag1)
    article1.tags.append(tag2)
    article2.tags.append(tag1)
    article2.tags.append(tag2)

    db.session.commit()
- 访问数据
article1 = Article.query.filter(Article.title == 'xiyou').first()
    tags = article1.tags
    print(article1.tags)
    for tag in tags:
        print('link-name: {}'.format(tag.name))

Flask-Script的介绍与安装:

  1. Flask-Script: Flask-Script的作用是可以通过命令行的形式来操作Flask,例如通过命令跑一个开发版本的服务器、设置数据库、定时任务等。
  2. 安装:首先进入到虚拟环境中, 然后pip3 install flask-script来进行安装。
  3. 如果直接在主manage.py 中写命令, 那么在终端就只需要python3 manage.py command_name 就可以了。
  4. 如果把一些命令集中在一个文件中,那么在终端中就需要输入一个命令,比如python3 manage.py db init
  5. 例子:
from  flask_script import Manager
from  Test_Script_demo import app
from db_scripts import DBManager

# 要初始化manager就需要使用到Flask框架
manage = Manager(app)

# 和数据库相关的操作,我都放在一起

@manage.command
def runserver():
  print("服务器已经运行起来了!!!")

# 终端运行结果:
# $ python3 manage.py runserver
#   服务器已经运行起来了!!


# 将DBManager中的命令全部引用到当前的manager的命令中
# db:使用命令时的前缀, DBManager添加的命令
manage.add_command('db',DBManager)

# 终端运行结果:
# $ python3 manage.py db init
#   数据库已经初始化完毕


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

  1. 有子命令的例子:

from flask_script import Manager

# 因为这里不需要直接运行这个管理类, 所以不需要传app进去
DBManager = Manager()

@DBManager.command
def init():
    print('数据库已经初始化完毕')

@DBManager.command
def migrate():
    print('数据表迁移成功')

终端命令调用方式:
localhost:~ liuzhanjun$ cd /Users/tangwenbin/Desktop/个人/python项目/Test_Script_demo 
localhost:Test_Script_demo liuzhanjun$ python3 manage.py runserver
服务器已经运行起来了!!!
localhost:Test_Script_demo liuzhanjun$ python3 manage.py db init
数据库已经初始化完毕
localhost:Test_Script_demo liuzhanjun$ python3 manage.py db migrate
数据表迁移成功
localhost:Test_Script_demo liuzhanjun$ 

分开Models和解决循环引用:

  1. 分开model的目的:为了让代码更加方便管理。

2.如何解决循环引用:把db放在一个单独文件中,切断循环引用的线条就可以了。

服务器沙箱操作:

  1. 我们虽然创建了一个新的app但是没有吧app放到需要渲染的栈里面去, 需要手动置顶当前要进入到栈里的app是哪一个:
# 指定当前的app需要进行入栈操作
with app.app_context():
    db.create_all()

Flask-Migrate的介绍与安装:

  1. 介绍: 因为采用db.create_all在后期修改字段的时候,不会自动的映射到数据库中,必须删除表,然后重新运行db.create_all才会重新映射,这样不符合我们的要求,因此flask-migrate就是为了解决这个问题,它可以在每次修改模型后,可以将修改的东西映射到数据库中。
  2. 首先进入到你的虚拟环境中,然后使用pip3 install flask-migrate进行安装就可以了。
  3. 使用flask-migrate必须借助flsk-scripts,这个包的MigrateCommand中包含了所有和数据库相关的命令。
  4. flask-migrarte相关的命令:
    • python3 manage.py db init: 初始化一个迁移脚本的环境,只需要执行一次
    • python3 manage.py db migrate:将模型生成迁移文件,只要模型更改了,就需要执行一遍这个命令。
    • python3 manage.py db upgrade: 将秦阿姨文件真正映射到数据库中,每次运行了 migrate命令后, 就需要运行这个命令。
  5. 注意点: 需要将你想要映射到数据库中的模型, 例如:from models import Article,都要导入到manage.py文件中,如果没有导入进去,就不会映射到数据库中。
from flask_script import Manager
from migrate_demo import app
from flask_migrate import Migrate, MigrateCommand
from exts import db
from models import Article

# init
# migrate
# upgrade
# 模型 -> 迁移文件 -> 表

manager = Manager(app)

# 1. 要使用flask-migrate,必须绑定app和db
migrate = Migrate(app, db)

# 2. 把MigrateCommand命令添加到manager中
manager.add_command("db", MigrateCommand)

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

cookie:

  1. cookie出现的原因:在网站中,http请求是无状态的。也就是说及时第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求时哪个用户,cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当用户已发送第二次请求的时候, 就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前是哪个了。
  2. 如果服务器返回了cookie给浏览器,那么浏览器下次再次请求相同的服务器的时候, 就会自动把cookie发送给浏览器,这个过程用户根本不需要管。
  3. cookie是保存在浏览器中的,相对的是浏览器

session:

  1. session介绍:session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取,但存储在服务器也有一定的弊端, 就是会占用服务器的资源, 但现在服务器已经发展至今,一些session信息还是绰绰有余的。
  2. 使用session的好处:
  • 铭感数据不是直接发送回给浏览器,而是发送回一个session_id,服务器将session_id和铭感数据做一个映射存储在session(在服务器上面)中,更加安全。
  • session可以设置过期时间,也从另外一方面,保证了用户的账号安全。

flask中的session工作机制:

  1. flask中的session机制是: 把铭感数据经过加密后放入session中, 然后再把session存放到cookie中,下次请求的时候, 再从浏览器发送过来的cookie中读取session,然后再从session中读取敏感数据,并进行解密,获取最终的用户数据。
  2. flask的这种session机制,可以节省服务器的开销,因为把所有的信息都存储到了客户端(浏览器)。
  3. 安全是相对的,把session放到cookie中,经过加密, 也是比较安全的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容