Flask教程(12)- 使用类视图实现前后端分离

0、前言:

  • 在学习类视图之前要了解前后端分离的概念,相对于之前的模板,前后端分离的模板会去除views文件,添加两个新python文件apis和urls,其中apis是用于传输数据和解析数据 的,urls是用于写模板路径的。
  • 1、Flask类视图和RESTful(前后端分离)

  • 前后端不分离:在之前用到的render_template(‘index.html’, users=users),这种的就是前后端不分离,这种方式在前后端进行数据交互的时候会非常方便,可以直接把后端数据传递给前端。
  • 前后端分离:后端会返回json字符串,前端使用ajax来请求数据。一般app就是通过前后端分离开发的,后端写后端的数据,前端写前端的数据,互不牵扯。app开发中,使用者手机中的是前端代码,后端代码是存放在服务器当中的。
  • HTTP请求方式:
  • GET :主要用来获取数据(网页请求获取服务器的数据)
  • POST :主要用来新增数据(网页向服务器提交数据)
  • PUT :主要用来修改数据(网页向服务器发送修改数据请求)
  • DELETE :主要用来删除数据(网页向服务器发送删除数据请求)
  • Flask类视图和RESTful主要服务于前后端分离,如果前后端不分离,就使用render_templlate。
  • Flask-RESTful是一种Flask插件
  • 字段格式化:用来规定返回给前端的数据格式,更加规范。
  • Url:也是fields中的一个返回数据类型
  • 参数解析:前端传递数据过来,需要做参数解析
  • 举例:通过下面的例子可以实现简单的前后端分离,了解如何通过类视图和RESTful实现前后端分离。
    项目概览:
  • __ init __:

    # __init__.py : 初始化文件,创建Flask应用
    from flask import Flask
    from .exts import init_exts
    from .urls import *
    
    def creat_app():
        app = Flask(__name__)
    
    
        # 配置数据库(配置不同数据库软件,就要用不同配置,配置的目的,就是在用到数据库的时候让项目知道找什么数据库,去哪找数据库)
        db_uri = 'sqlite:///sqlite3.db'
        # db_uri = 'mysql+pymysql://root:123456@localhost:3306/flaskdb' # mysql的配置
        app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 禁止对象追踪修改(为了不浪费服务器资源进行的设置)
    
        # 初始化插件
        init_exts(app=app)
    
        return app
    

    apis:

    from flask import jsonify
    from flask_restful import Resource, fields, marshal_with, reqparse
    from .models import *
    
    # 字段格式化---------------------------------
    user_fields = {
        'name' : fields.String,
        'age' : fields.Integer
    }
    # 在字段格式化时嵌入另一个字段格式化
    ret_fields = {
        'status' : fields.Integer,
        'msg' : fields.String,
        'user' : fields.Nested(user_fields),
        'url' : fields.Url(endpoint='id',absolute=True) # 在urls中endpoint='id'写在哪,url就是哪个根路径
    }
    # 如果获取多个对象列表就要嵌入下面格式化方法
    ret_fields2 = {
        'status' : fields.Integer,
        'msg' : fields.String,
        'user' : fields.List(fields.Nested(user_fields))
    }
    # ---------------------------------字段格式化---------------------------------
    # 没有加字段格式化
    class UserResource(Resource):
        def get(self):
            return {
                'status' : 1,
                'msg' : 'ok',
                'data' : '千峰教育python',
            }
    # 添加字段格式化(导入一个数据库对象)
    class Usera(Resource):
        @marshal_with(ret_fields)
        def get(self):
            user = User.query.first()
            return {
                'status' : 1,
                'msg' : 'ok',
                'data' : '千峰教育python',
                'user' : user
            }
    # 没有加字段格式化(导入多个数据库对象)
    class Usera1(Resource):
        @marshal_with(ret_fields2)
        def get(self):
            user = User.query.all()
            return {
                'status' : 1,
                'msg' : 'ok',
                'data' : '千峰教育python',
                'user': user
            }
    
    # --------------------------------- 参数解析---------------------------------
    # 参数解析: 主要解析前端发送过来的数据,对前端发送过来的数据做一些限制
    parse = reqparse.RequestParser()
    parse.add_argument('name', type=str, required=True, help='name is must!') # required=True表示该参数必须传递
    parse.add_argument('age', type=int, action='append') # action=append表示这个参数可以传多个
    
    class Usera2(Resource):
        def get(self):
            # 获取参数
            args = parse.parse_args()
            name = args.get('name')
            age = args.get('age')
    
            return {'name':name,'age':age} # 返回获取的参数
    

    exts:

    from flask_sqlalchemy import SQLAlchemy # orm技术
    from flask_migrate import Migrate # 数据迁移技术
    from flask_restful import Api
    
    db = SQLAlchemy()
    migrate = Migrate()
    api = Api()
    
    def init_exts(app):
        db.init_app(app=app)
        migrate.init_app(app=app, db=db)
        api.init_app(app=app)
    

    models:

    # models.py : 模型,数据库
    '''
        模型      ===      数据库
        类        ——>     表结构
        类属性     ——>    表字段
        一个对象   ——>    表的一行数据
    '''
    from .exts import db # 导入db对象就能通过python实现ORM技术,避免了写SQL语句。
    
    # 模型Model:类
    # 必须继承 db.Model User才能从普通的类变成模型
    class User(db.Model):
        # 表名
        __tablename__ = 'user'   # 数据迁移就是让模型变成表,ORM就是让类变成模型
        # 定义表字段
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        name = db.Column(db.String(30), unique=True)
        age = db.Column(db.Integer, default=1)
        # 通过orm技术得到的db,就是用于替代数据库,后面用到数据库相关操作,可以检索。
    

    urls:

    # urls是路由文件
    from .exts import api
    from .apis import *
    
    # 路由
    api.add_resource(UserResource, '/UR/', endpoint='id') # 这里endpoint和apis中endpoint是id的路径关联
    api.add_resource(Usera, '/U/')
    api.add_resource(Usera1, '/U1/')
    api.add_resource(Usera2, '/U2/')
    

    app:

    # Flask类试图和restful
    from App import creat_app
    
    app = creat_app()
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    假前端:

    import requests
    
    # res1 = requests.get('http://127.0.0.1:5000/hello/')
    # res2 = requests.post('http://127.0.0.1:5000/hello/')
    a = requests.get('http://127.0.0.1:5000/U2/',
                     json={'name':'zhangsan','age':12},
                     headers={'Content-Type':'application/json'}
                     )
    print(a.text)
    

    总结:

    1、前后端分离的Flask模板相对于前后端不分离的模板而言,少了views这个文件,它相当于把views这个文件的功能分配到了apis和urls这两个文件中。apis主要写的是接口,urls主要写接口路由。
    2、在api文件中字段格式化的作用是定义返回给前端的数据格式。
    3、在api文件中参数解析的作用是解析前端发送过来的数据。

    作者:疋瓞

    物联沃分享整理
    物联沃-IOTWORD物联网 » Flask教程(12)- 使用类视图实现前后端分离

    发表回复