python学习(四):犹如鸿雁一般的Flask,小小框架有着无限可能

1.Flask安装
1.创建项目

pip install Flask                                     安装Flask模块

python -m  flask run (--host=0.0.0.0)                运行项目(默认5000端口)
    
2.项目结构
FlaskAdmin
│  app.py                            主入口文件 
├─static                              静态资源文件
│  └─css
│          index.css 
└─templates                          模板文件
    └─home
            index.html

(1.默认结构

from flask import Flask,request,redirect,url_for,render_template

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'hello world'
  
# 以脚本的形式运行,以命令行的形式运行,默认情况下,都没有实现热重载功能 
if __name__ == '__main__':
    app.run(debug=True) 

(2.热重载结构


使用pycharm 右上角的脚本运行方式有热重载功能,而命令行启动方式无效

注意:1.这种方式只监听保存的代码。2.如果遇到异常,会立即退出。  3.一般增加功能会执行热重载。

2.Flask全栈学习
1.@app.route路由注解
1.route路由功能

1.methods请求注解


@app.route("/")
def hello_world():
    # html=""
    # lxml_demo.parse_page_lxml(html)
    return render_template('intro.html')

### 注解中声明请求方法
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return "这是post方法"+request.form['username']
    else:
        return "这是get方法"

2.route多重路由注解(可变)


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

3.path路径参数路由


### 路径参数: string类型
## /user/xiaoming
@app.route('/user/<username>/')
def shwo_user_profile(username):
    return f'User {username}'


### 路径参数: int类型
## /post/1
@app.route('/post/<int:post_id>')
def shwo_post(post_id):
    return f'Post {post_id}'

4.query参数路由


# ### query参数: request.args.get('xxx')获取
# @app.route ('/profile/')
# def profile():
#     if request.args.get ('name'):
#         return '个人中心页面'
#     else:
#         return redirect (url_for ('register'))
#

5.404错误页


@app.errorhandler(404)
def page_not_found(error):
	return render_template ('404error.html')

2.views视图函数

1.url_for路由别名

路由别名指向视图函数,而不受注解影响

### 视图函数的别名
## url_for('my_list',page=1,count=2)
## 构建出来的url:/post/list/1/?count=2
@app.route('/post/list/<page>/')
def my_list(page):
    return 'my list'


模板中使用 
<a href="{{ url_for('salut') }}">链接</a>  
# 好处是路由可以随便改,不影响代码. 这里的参数是相应函数名(不带括号的)

2.render_template返回模板


## 模板文件
## flask采用Jinjia2作为模板,模板文件默认放置在templates文件夹(Django也是templates, 模板语法和Django类似) 
def hello(name=None):
    return render_template ('home/index.html', name=name)

3.redirect路由重定向(url_for)

 
### query参数: request.args.get('xxx')获取
@app.route ('/profile/')
def profile():
    if request.args.get ('name'):
        return '个人中心页面'
    else:
        return redirect (url_for ('register'))    // 跳转指定的视图函数
        return redirect ('/register')             // 跳转指定的路由
 

3.Markup解析标签

Markup帮助咱们在HTML的标签上做了一层封装,让Jinja2模板语言知道这是一个安全的HTML标签。前端只需要在模板语法中加上一个safe就额可以了

后端 : 
from flask import Markup  
    tag = "<input type='text' name='user' value='DragonFire'>" 
    markup_tag = Markup(tag)
      
前端 : 
{{ tag|safe }}  

4.template_global全局注解

@app.template_global()  # 定义全局模板函数
def a_b_sum(a, b):
    return a + b
    
#定义一个全局函数,这样就不需要进行传递,可以在全局使用
2.templates模板语法
1.static静态资源

#Web程序中常常需要处理静态文件,在Flask中需要使用url_for函数并指定static端点名和文件名。 

### 1.模板文件中使用静态资源 
(1.方法一:使用url_for模板语法
<link rel="stylesheet" href="{{url_for('static',filename='css/index.css')}}">
  
(2.方法二:在setting添加对应的配置文件 
  <img src="/static/img/bg-main.png" alt="">  (添加上根路径下的文件就可以)
  
### 2.在视图函数中使用模板文件 myhome/views.py
def func(request):
	return render_template(request,'a/ind.html')
    
### 3.直接访问静态资源
// static 类似于其它框架的public目录,但Django框架需要携带这个目录
http://localhost:5000/static/assets/upload/image/bgmain-1.png   

2.if…else,for…in语法

if…else,for…in和extend,include,Flask和Django相同

注意点:比如include加载有延迟,因此使用Django的方式开发flask, 效果并不理想。 特别是对加载Script脚本时,影响最大

{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

{% for foo in g %}
.....
{% endfor %}
3.{{ }}过滤器

(1.模板过滤器

{{name | upper}}             名称大写

(capitalize 首字母大写,trim 去空格, lower 转小写, upper 转大写)

(2.模板函数

# 1.视图函数
#定义一个函数,把它传递给前端
def a_b_sum(a,b):
    return a+b

@app.route("/")
def index():
	## 传递模板函数
    return render_template("index.html", tag=a_b_sum) 
    ## 传递列表数据
    return render_template ('charts.html',lxml_listl=self.lxml_list) 
    
    
# 2.模板页面
{{ tag(99,1) }}

注意:如果没有使用{% comment %} 注释,则会出现异常

(3.枚举遍历

Jinjia2模板页面中不认识enumerate关键字

1.在视图函数中先进行枚举
if keyword =='charts':
	return render_template ('charts.html',lxml_list=enumerate(self.lxml_list))

2.再采用模板语法 
 {% for i,item in lxml_list  %}
    <tr>
      <td>{{i+1}}</td>
      <td>{{item["authors"]}}</td>
      <td>{{item["tags"]}}</td>
      <td>{{item["quotes"]}}</td>
    </tr>
 {% endfor %}

3.models数据库模型
1.配置数据库
  1. sqlalchemy:是一个独立的ORM框架,可以独立于Flask存在,也可以在其他项目中使用,比如Django中。

  2. flask-sqlalchemy:对sqlalchemy的一个封装,能够更适合在flask中使用。

一、安装模块
1、安装连接数据库的库:
pip install pymysql

2、安装封装后sqlalchemy: 
pip install flask-sqlalchemy


二、配置文件
from flask_restful import Api, Resource
from flask_sqlalchemy import SQLAlchemy

#创建一个对象,设置名为db
db = SQLAlchemy(app) 
# "mysql://账号:密码@数据库ip地址:端口号/数据库名"
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:mysql@192.168.44.128:3306/test39"
# 关闭数据库修改跟踪操作[提高性能],可以设置为True,这样可以跟踪操作:
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 开启输出底层执行的sql语句
app.config['SQLALCHEMY_ECHO'] = True
# 开启数据库的自动提交功能[一般不使用]
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True 
# 未知的配置功能
# app.config['SQLALCHEMY_BINDS'] = {}


三、处理python3和python2的兼容性
python2中数据库客户端: MySqldb
python3中数据库客户端:pymysql
解决方案一:让python2和python3的包进行转换。
import pymysql
pymysql.install_as_MySQLdb() 
方案二:表示只使用python3的包,不使用python2的包
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://xxxxx"

四、安装模块的注意事项
(1.如果在terminal中安装成功后,flask-sqlalchemy导入失败,则可以在pycharm的pip设置选项中添加这个模块
(2.如果出现PyMysql 找不到的情况下,在app.py中添加以下代码
import pymysql
pymysql.install_as_MySQLdb()

2.sqlalchemy模型使用

数据操作——增删改查
1:给模型对象设置数据 可以通过 初始化参数 或者 赋值属性 两种方式
2:session.add(模型对象) 添加单条数据到会话中, session.add_all(列表) 添加多条数据到会话中
3:sqlalchemy 会 自动创建事务, 并将数据操作包含在事务中, 提交会话时就会提交事务,事务提交失败会自动回滚。

**(1.**基本的使用

## (1.创建一个对象,设置名为db
##(注意需要在配置app.config数据库前,创建实例)
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app) 
## 配置数据库
app.config = {**app.config, **config}

## (3.如果需要重建表,可以考虑以下内容(?)
# 删除表 
db.drop_all()  
# 创建表 
db.create_all() 

## (2.验证是否连接成功
engine = db.get_engine()
conn = engine.connect()
conn.close() 
# 也可以执行sql语句
# with engine.connect() as conn:
# 	result = conn.execute('select 1')  
# 	print (result.fetchone()) 

**(2.**模型的关联

教程链接:https://blog.csdn.net/qq_42385761/article/details/122792767


## (1.外键
#1.外键的数据类型一定要注意所引用的字段类型。db.Foreignkey("表名. 字段名")
#3.外键是属于数据库层面的,不推荐直接在ORM直接使用
author_id = db.Column(db.Integer,db.Foreignkey("user.id"))

## (2.关联
#1.第一个参数是模型的名字,必须要和模型的名字一致(被连接的)。backref(bsck reference)。
#2.代表反向引用,代表对方访问我的时候的字段名称
author = db.relationship("user",backref="articles")

## (3.一对一:
# db.backref
#1. 在反向引用的时候,如果需要传递一些其他的参数,那么就需要用到这个函数,否则不需要使用。
#2.只要在relationship的backref参数上,设置反向引用的名称就可以了。uselist=Flase :代表反向引用的名称就可以了
user = db.relationship("User",backref=db.backref("extension",uselist=Flase))

## (4.新建数据库表,创建orm模型
class Books(db.Model):
	__tablename__ = 'Books'  # 设置表名
	id = db.Column(db.Integer,primary_key=True,autoincrement=True) # 主键字段
	title = db.Column(db.String(200),nullable=False)  # 标题
	content = db.Column(db.Text,nullable=False)  # 内容

class User(db.Model):
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(20))
    addresses = db.relationship('Address',backref='user')

class Address(db.Model):
    id = db.Column(db.Integer,primary_key=True)
    email_address = db.Column(db.String(50))
    user_id = db.Column(db.Integer,db.ForeignKey('user.id'))

3.sqlacodegen反向映射*
  1. flask-sqlacodegen,他的作用就是将数据库转换成模型

  2. sqlacodegen的包是否删除(用flask-sqlacodegen就不能有sqlacodegen包,会有重复包名,会导致调用失败)

1.安装模块(下载失败可以在pycharm里面安装)
pip3 install flask-sqlacodegen==1.1.6 

2.执行命令(需要停止运行程序)
python -m flask-sqlacodegen mysql+mysqldb://root:123456@127.0.0.1:3306/flask-test > models.py --flask

注意:映射的模型文件,会清空原有的数据。

4.migrate模型映射
  1. 在实际的开发环境中,经常会发生数据库修改的行为。一般我们修改数据库不会直接手动的去修改,而是**去修改ORM对应的模型,然后再把模型映射到数据库**中。这时候如果有一个工具能专门做这种事情,就显得非常有用了,而flask-migrate就是做这个事情的。

  2. flask-migrate是基于Alembic进行的一个封装,并集成到Flask中,而所有的迁移操作其实都是Alembic做的,他能跟踪模型的变化,并将变化映射到数据库中。

注意:如果已经有映射文件(migrations)和映射表(alembic_version),则需要先删除再重新初始化。

1.安装模块
pip install flask-migrate

2.使用方法(在定义模型的位置前后都可以)
from flask_migrate import Migrate
(1.模型注册到当前应用
db.init_app (app)
(2.绑定app和数据库
migrate = Migrate(app,db)


3.使用命令执行映射ORM
python -m flask db init                        初始化一个迁移文件夹 
python -m flask db migrate                     把当前的模型添加到迁移文件中 
python -m flask db upgrade                     把迁移文件中对应的数据库操作,真正的映射到数据库中:

(1. 数据库会生成一个alembic_version,是映射对应的id, 如果需要重新映射,也需要把这个表给手动删除。
(2. 把原有的migrations文件夹给删除
5.常用模型字段

1.常用数据类型

Integer:整形,映射到数据库中是int类型。
Float:浮点类型,映射到数据库中是flfloat类型。他占据的32位。
Double:双精度浮点类型,映射到数据库中是double类型,占据64位 (SQLALCHEMY中没有)。
String:可变字符类型,映射到数据库中是varchar类型.
Boolean:布尔类型,映射到数据库中的是tinyint类型。
DECIMAL:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存储多少个数字,第二个参数表示小数点后有多少位。
Enum:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来作为枚举。
Date:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用datetime.date 来指定。
DateTime:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码中,可以使用 datetime.datetime 来指定。
Time:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用datetime.time 来创建值。
Text:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。
LONGTEXT:长文本类型,映射到数据库中是longtext类型。 

2.Column常用参数

primary_key:True设置某个字段为主键。
autoincrement:True设置这个字段为自动增长的。
default:设置某个字段的默认值。在发表时间这些字段上面经常用。
nullable:指定某个字段是否为空。默认值是True,就是可以为空。
unique:指定某个字段的值是否唯一。默认是False。
onupdate:在数据更新的时候会调用这个参数指定的值或者函数。在第一次插入这条数据的时候,不会用 onupdate的值,只会使用default的值。常用于是 update_time 字段(每次更新数据的时候都要更新该字段值)。
name:指定ORM模型中某个属性映射到表中的字段名。如果不指定,那么会使用这个属性的名字来作为字段名。如果指定了,就会使用指定的这个值作为表字段名。这个参数也可以当作位置参数,在第1个参数来指定。 
4.data数据获取
1.获取MySQL数据

1.普通的CRUD

# 1. 添加数据 
article = User(title = "标题", content = "内容") 
db.session.add (article) 
db.session.commit ()
 
# 2.查询数据
# filter_by() 返回一个类列表的对象
obj_list = User.query.filter_by (id=1).all()  
# first() 返回第一个对象
obj = User.query.filter_by (id=1).first()  
 
# 3.修改数据
# 更新单个数据
obj = db.session.query(UserMsg).filter_by(id=obj.id)[0]
obj.token = token
db.session.commit () 
# 更新多个数据
obj_list = db.session.query(UserMsg).filter_by(email=obj.email).all()
for item in obj_list:
	item.token = token
db.session.commit ()

# 4.删除数据
obj = User.query.filter_by (id=1)
obj.delete ()
db.session.commit ()
    

2.高级查询

# 1.模糊查询
# or_() 或查询数据
artice = User.query.filter_by (or_(id=1)).all() 
# ilike是不区分大小写,like是区分大小写
user_list = UserMsg.query.filter(UserMsg.username.like(f'%{username}%')).all ()

# 2.偏移查询
# offset() 跳过n条数据查询
artice = User.query.offset(2).filter_by (or_(id=1)).first() 
# limit() 获取n条数据
artice = User.query.offset(2).filter_by (or_(id=1)).limit(10).first() 
# [start:stop], slice(start,stop) 切片获取数据
artice = User.query.offset(2).filter_by (or_(id=1)).slice(0,10).first() 

# 3.排序
# order_by() 排序 (asc(), desc())
artice = User.query.filter_by (id=1).order_by(User.id.desc()).all() 

# 4.分组查询
# group_by() 根据某些字段分组
# 如想要根据年龄进行分组,来统计每个分组分别有多少人
user_result = db.session.query(User.id,func.count(User.id)).group_by(User.sex).all()

2.获取Request数据
from flask import request

def login():
	curmethod = request.method                请求方法(request包含请求的各种变量 )
	name = request.args.get("xxx")            获取get方法的query参数
	name = request.values.get("xxxx")         获取get方法的query参数(建议使用) 
	data = request.form                       获取post请求的参数 
	headers = request.headers                 获取headers请求头数据
    fileName = request.values.get("file")   获取上传的文件
	data = request.get_data()                 获取请求的所有数据
	
3.获取Response数据

# 普通返回字典数据
from flask import jsonify
def dowonload(): 
    return jsonify({ 'msg':'下载成功!','code':200 })
 
# 序列化数据集对象(模板传递数据不需要序列化)
from collections import Iterable 
def serialize_models(modelsObj):
    try:
        # 可迭代对象是转换成列表,否则转换成字典
        if isinstance(modelsObj, Iterable):
            # 序列化成列表格式
            # 清洗列表数据(列表推导式)
            t_modelsObj = []
            for item in modelsObj:
                t_modelsObj.append({key: value for key, value in item.__dict__.items ()  if key != '_sa_instance_state' })
            modelsObj = list.copy(t_modelsObj)
        else:
            modelsObj = {key: value for key, value in modelsObj.__dict__.items () if key != '_sa_instance_state' }
        return modelsObj
    except Exception as e:
        print("序列化数据集对象异常",e)
        return None

5.Filter 拦截器
1.session身份认证

1.普通使用

如果有redis等缓存需求,可以安装Flask-Session

教程链接:https://blog.csdn.net/lluozh2015/article/details/123174344

from flask import session

# 配置session
app.config['SECRET_KEY'] = os.urandom(24)
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  

# 设置session
session['username'] = 'liefyuan'

# 获取session
# 如果内容不存在,将会报异常
result = session['key'] 
# 如果内容不存在,将返回None(推荐)
result = session.get('key')

# 删除session
session.pop('username',None) 

# 清空session
session.clear

## 页面中使用 session
{{ session.user.username}}

2.封装成拦截器


# 路由拦截器  
    @app.before_request
    def before():
        url = request.path  # 当前请求的URL
        passUrl = ["/login", "/register","/auth/doLogin", "/auth/doRegister"]
        if url not in passUrl and not url.startswith("/static"):
            user = session.get ("user", None)
            if not user or not user.get("id"):
                return redirect("/login")
            else:
                # 验证帐号是否有效
                user_id = user.get("id")
                obj = UserMsg.query.filter_by (id=user_id,is_delete=0).first()
                if not obj:
                    return redirect("/login")
                else:
                    pass
        else:
            pass
   
## 保存信息
# 保存到session里面
    obj = obj_list[0]
    session['user'] = {
        "id":obj.id,
        "username":obj.username,
        "email":obj.name,
    }
6.分离项目拦截器
1.flask_cors跨域
1.安装模块
pip install flask_cors

2.使用方法
from flask_cors import CORS
# r'/*' 是通配符,让本服务器所有的 URL 都允许跨域请求
CORS(app, resources=r'/*')

2.PyJWT身份认证

(1.定义JWT方法

1.安装模块(这个模块与Django的相同)
pip install PyJWT


2.使用方法
--/utils/JWT.py  实现jwt操作
    import jwt
    import datetime

    # 加密密钥
    secret_key = 'xxxx'

    # 一、生成token密钥
    # 传入的数据为 use_id 最好不要添加其它参数,否则会超过最大值240, 目前是 176长度
    # 可修改参数:  valid_days  有效期天数可以修改,  secret_key   服务器密钥也可以修改
    ## data为字典数据
    # 1.有效载核,存放有效信息   2.密钥字串, 服务端被重置时的合法性      3.sinature签名算法
    # 返回token字符串值 和 token数据
    def make_jwt(user_id):
        try:
            global secret_key
            now_time = datetime.datetime.now ()
            str_now_time = datetime.datetime.strftime (now_time, '%Y-%m-%d %H:%M:%S')
            token_input_data = {
                'user_id': user_id,  # 用户ID,或者其它参数
                'now_time': str_now_time,  ## 当前的用户登录信息, 日期字符串
                'valid_days': 15  # 天数 days
            }
            encoded_jwt = jwt.encode (token_input_data, secret_key, algorithm='HS256')
            if type (encoded_jwt) != str:  ## 转换成普通的string字符串
                encoded_jwt = str (encoded_jwt, encoding="utf-8")
            return encoded_jwt
        except Exception as e:
            print ("错误是", e)
        return None


    # 二、解析token密钥
    ## str_token 为token字符串
    ## 返回验证结果 user_data /  None
    def parse_jwt(str_token):
        try:
            global secret_key
            if type (str_token) != bytes:
                str_token = bytes (str_token, encoding='utf8')
                # 解密token
            token_output_data = jwt.decode (str_token, secret_key, algorithms=['HS256'])
            # 检测token的有效性
            str_pass_time = token_output_data.get ('now_time', None)
            str_valid_days = token_output_data.get ('valid_days', None)
            if len (str_pass_time) == 0 or str (str_valid_days) == 0:
                raise Exception ('error')
            obj_pass_time = datetime.datetime.strptime (str_pass_time, '%Y-%m-%d %H:%M:%S')
            obj_valid_time = obj_pass_time + datetime.timedelta (days=str_valid_days)
            now_time = datetime.datetime.now ()
            if obj_valid_time < now_time:
                raise Exception ('error')
            else:
                return token_output_data
        except Exception as e:
            print ("错误是", e)
        return None


    # 三、jwt直接获取 user_id 参数值
    # 获取 token,   META 获取数据  ”HTTP_ + header字段名称大写“
    # 使用.get获取与是否在请求中使用get方法无关
    def get_parse_token(request):
        try:
            global secret_key
            str_token = request.headers.get("token",None)  # 获取 token
            if type (str_token) != bytes:
                str_token = bytes (str_token, encoding='utf8')
                token_output_data = jwt.decode (str_token, secret_key, algorithms=['HS256'])
                return token_output_data['user_id']
            else:
                return None
        except Exception as e:
            print ("错误是", e)
            return None




-- views/UserViews.py视图函数 
    from ..utils import JWT          # 自定义jwt生成token模块

    token = JWT.make_jwt(user_id)             # 生成token
    user_obj = JWT.parse_jwt(token)           # 解析token
	user_id = JWT.get_parse_token(request)    # 获取token数据

(2.jwt拦截器


    # 路由拦截器
    @app.before_request
    def before():
        url = request.path  # 当前请求的URL
        passUrl = ["/","/login", "/register"]
        if url not in passUrl and not url.startswith("/static"):
            token = request.headers.get("token")
            # 验证是否有token
            if not token:
                return jsonify({ 'msg':'无权限访问!请输入token!','code':403 })
            else:
                # 验证token是否有效
                user_id = jwt.get_parse_token(request)
                if not user_id:
                    return jsonify({ 'msg':'无权限访问!token无效!','code':403 })
                else:
                    # 验证帐号是否有效
                    obj = UserMsg.query.filter_by (id=user_id,is_delete=0).first()
                    if not obj:
                        return jsonify({ 'msg':'无权限访问!当前帐号已被注销!','code':403 })
                    else:
                        pass
        else:
            pass
7.flask功能模块
1.passlib密码加密
1.安装模块
pip install passlib

2.使用方法
from passlib.hash import pbkdf2_sha256

# 密码加密
encryptPass = pbkdf2_sha256.hash("123456")
print("加密数据",encryptPass)

# 验证密码
res = pbkdf2_sha256.verify("123456",encryptPass)
print("验证数据",res)

2.服务端文件下载

// 返回静态页面

# import urllib.request
# url = "http://127.0.0.1:5000/"
# res = urllib.request.urlopen(url)
# data = res.read().decode()
# print(data)


import flask
app = flask.Flask(__name__)
# 路由就是将URL绑定到一个函数上面,这样浏览器客户端向web服务器发送一个URL请求后,服务器中的路由收到这个URL后,能立马找到对应的函数进行处理。
@app.route("/")        
# 这是一段路由控制语句,每个路由地址用“@app.route(...)来指明,来访问的相对地址是“/”
def index():
    try:
        res = open('2.hello.html',"rb")
        data = res.read()
        res.close()
        return data
    except Exception:
        print('error')

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

// 下载文件"图像.jpg"


import flask
import os
app=flask.Flask(__name__)
@app.route("/")
def index():
    if "fileName" not in flask.request.values:
        return "图像.jpg"
    else:
        data = b""
        try:
		       fileName = flask.request.values.get("fileName")
            if fileName != "" and os.path.exists(fileName):
                fobj = open(fileName, "rb")
                data = fobj.read()
                fobj.close()
                ## 返回二进制流
          except Exception as err:
            data = str(err).encode()
        return data
if __name__=="__main__":
    app.run()
3.file上传文件

//获取文件名称fileName,然后获取文件数据保存

import flask
app=flask.Flask(__name__)
@app.route("/upload",methods=["POST"])
def uploadFile():
    msg=""
    try:
        if "fileName" in flask.request.values:
            fileName = flask.request.values.get("fileName")      
		            data=flask.request.get_data()
            fobj=open("upload "+fileName,"wb")
            fobj.write(data)
            fobj.close()
            msg="OK"
            
            ## 存入本地
        else:
            msg="没有按要求上传文件"
   except Exception as err:
        print(err)
        msg=str(err)
    return msg
if __name__=="__main__":
    app.run()

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值