flask---》Marshmallow介绍及基础使用

0. Marshmallow背景介绍

介绍

  • Marshmallow,中文译作:棉花糖。
  • 是一个轻量级的数据格式转换的模块,也叫序列化和反序列化模块,常用于将复杂的orm模型对象与python原生数据类型之间相互转换。
  • 一般用于flask
  • marshmallow提供了丰富的api功能。如下:
  1. Serializing

    序列化[可以把数据对象转化为可存储或可传输的数据类型,例如:objects/object->list/dict,dict/list->string]

  2. Deserializing

    反序列化器[把可存储或可传输的数据类型转换成数据对象,例如:list/dict->objects/object,string->dict/list]

  3. Validation

    数据校验,可以在反序列化阶段,针对要转换数据的内容进行类型验证或自定义验证。

官方文档:

marshmallow: simplified object serialization — marshmallow 3.15.0 documentationhttps://marshmallow.readthedocs.io/en/latest/

1. 使用

1. 安装

pip3 install -U marshmallow-sqlalchemy -i https://pypi.douban.com/simple
pip3 install -U flask-sqlalchemy -i https://pypi.douban.com/simple
pip3 install -U flask-marshmallow -i https://pypi.douban.com/simple
pip3 install -U pymysql -i https://pypi.douban.com/simple

2. flask连接mysql介绍 

# 格式
"mysql://用户名:密码@ip:端口/库名称?charset=utf8mb4"

# 案例
"mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"

3. 模块初始化:

from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetime

import pymysql

pymysql.install_as_MySQLdb()
# 实例化

app = Flask(__name__)

# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)


class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    username = db.Column(db.String(255), index=True, comment="用户名")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(15), index=True, comment="手机号码")
    sex = db.Column(db.Boolean, default=True, comment="性别")
    email = db.Column(db.String(255), index=True, comment="邮箱")
    created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")
    updated_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.name, self.username)


@app.route("/")
def index():
    return "hello"


if __name__ == '__main__':
    with app.app_context():
        # db.drop_all()
        db.create_all()

    app.run(debug=True, host='127.0.0.1', port=7800)

4. Marshmallow序列化基础使用

  • 只有4.1是完整的代码,其他的只提供Marshmallow的代码,初始化的代码,就不在重复写了

schema常用属性数据类型

类型描述
fields.Dict(keys, type]] = None, values, …)字典类型,常用于接收json类型数据
fields.List(cls_or_instance, type], **kwargs)列表类型,常用于接收数组数据
fields.Tuple(tuple_fields, *args, **kwargs)元组类型
fields.String(*, default, missing, data_key, …)字符串类型
fields.UUID(*, default, missing, data_key, …)UUID格式类型的字符串
fields.Number(*, as_string, **kwargs)数值基本类型
fields.Integer(*, strict, **kwargs)整型
fields.Decimal(places, rounding, *, allow_nan, …)数值型
fields.Boolean(*, truthy, falsy, **kwargs)布尔型
fields.Float(*, allow_nan, as_string, **kwargs)浮点数类型
fields.DateTime(format, **kwargs)日期时间类型
fields.Time(format, **kwargs)时间类型
fields.Date(format, **kwargs)日期类型
fields.Url(*, relative, schemes, Set[str]]] = None, …)url网址字符串类型
fields.Email(*args, **kwargs)邮箱字符串类型
fields.IP(*args[, exploded])IP地址字符串类型
fields.IPv4(*args[, exploded])IPv4地址字符串类型
fields.IPv6(*args[, exploded])IPv6地址字符串类型
fields.Method(serialize, deserialize, **kwargs)基于Schema类方法返回值的字段
fields.Function(serialize, Any], Callable[[Any, …)基于函数返回值得字段
fields.Nested(nested, type, str, Callable[[], …)外键类型

Schema数据类型的常用通用属性

属性名描述
default序列化阶段中设置字段的默认值
missing反序列化阶段中设置字段的默认值
validate反序列化阶段调用的内置数据验证器或者内置验证集合
required设置当前字段的必填字段
allow_none是否允许为空 None,""
load_only是否在反序列化阶段才使用到当前字段,相当于之前的write_only
dump_only是否在序列化阶段才使用到当前字段,相当于之前的read_only
error_messages字典类型,可以用来替代默认的字段异常提示语,格式: error_messages={“required”: “用户名为必填项。”}

单个表模型序列化成字典或json字符串

  • 代码
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetime

import pymysql

pymysql.install_as_MySQLdb()
# 实例化

app = Flask(__name__)

# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)


class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    username = db.Column(db.String(255), index=True, comment="用户名")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(15), index=True, comment="手机号码")
    sex = db.Column(db.Boolean, default=True, comment="性别")
    email = db.Column(db.String(255), index=True, comment="邮箱")
    created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")
    updated_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.name, self.username)


# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields


# 类似与django的from组件
class UserSchema(Schema):
    username = fields.String()
    mobile = fields.String()
    email = fields.Email()
    create_time = fields.DateTime()


@app.route("/")
def index():
    # 模拟数据
    user = User(
        username="xiaoming",
        mobile="13312345677",
        sex=True,
        email="133123456@qq.com",
        created_time=datetime.now(),
        updated_time=datetime.now()
    )
    # 调用marsh把模型转换成python基本数据格式[字典/列表]
    us = UserSchema()
    # 转换成字典
    ret1 = us.dump(user)
    # 转换成json字符串(它是双引号的)
    ret2 = us.dumps(user)
    print(">>>> 原生  --> 对象")
    print(User)
    print(">>>> us.dump(user)  --> 字典")
    print(ret1)
    print(">>>> us.dumps(user) --> json字符串")
    print(ret2)
    return "hello"


if __name__ == '__main__':
    with app.app_context():
        # db.drop_all()
        db.create_all()

    app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
>>>> 原生  --> 对象
<class '__main__.User'>
>>>> us.dump(user)  --> 字典
{'username': 'xiaoming', 'mobile': '13312345677', 'email': '133123456@qq.com'}
>>>> us.dumps(user) --> json字符串
{"username": "xiaoming", "mobile": "13312345677", "email": "133123456@qq.com"}

多个表模型序列化成字典或json字符串

  • 代码
# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields


# 类似与django的from组件
class UserSchema(Schema):
    username = fields.String()
    mobile = fields.String()
    email = fields.Email()
    create_time = fields.DateTime()


@app.route("/")
def index():
    # 模拟数据
    user = User(
        username="xiaoming",
        mobile="13312345677",
        sex=True,
        email="133123456@qq.com",
        created_time=datetime.now(),
        updated_time=datetime.now()
    )
    user1 = User(
        username="xiaoming1号",
        mobile="13312345677",
        sex=True,
        email="133123456@qq.com",
        created_time=datetime.now(),
        updated_time=datetime.now()
    )

    user2 = User(
        username="xiaoming2号",
        mobile="13312345677",
        sex=True,
        email="133123456@qq.com",
        created_time=datetime.now(),
        updated_time=datetime.now()
    )

    user_list = [user, user1, user2]
    us = UserSchema()
    data_list = us.dump(user_list, many=True)
    print(data_list)
    return "hello"


if __name__ == '__main__':
    with app.app_context():
        # db.drop_all()
        db.create_all()

    app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
[
{'username': 'xiaoming', 'mobile': '13312345677', 'email': '133123456@qq.com'},
{'username': 'xiaoming1号', 'mobile': '13312345677', 'email': '133123456@qq.com'}, 
{'username': 'xiaoming2号', 'mobile': '13312345677', 'email': '133123456@qq.com'}
]

5. 高级使用

序列化嵌套

  • 代码
from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetime

import pymysql

pymysql.install_as_MySQLdb()
# 实例化

app = Flask(__name__)

# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)


# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields, ValidationError, validates_schema, validates, validate

"""
模拟表类型
User表中有两个外键 friends/books
Blog 有一个外键 author
"""


class User(object):
    def __init__(self, name, email):
        self.name = name
        self.email = email
        self.created_at = datetime.now()
        self.books = []
        self.friends = []


class Blog(object):
    def __init__(self, title, author):
        self.title = title
        self.author = author  # 用来代替MySQL中的外键关系


class BlogSchema(Schema):
    title = fields.String()
    # 使用lambda匿名函数,使只有在使用author时才会找UserSchema对象,不然可能出现先后调用,导致对象找不到的情况出现
    # 用来序列化外键对象,可以将外键对象按照指定的格式进行序列化,并且外键指定的格式可以完成任何支持的marshmallow操作
    author = fields.Nested(lambda: UserSchema())


class UserUserSchema(Schema):
    name = fields.String()
    email = fields.String()


class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    created_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
    # 双向嵌套,例如找出所有属于该用户的所有书籍。注意:在大数据量时,数据返回将非常慢
    books = fields.List(fields.Nested(BlogSchema(exclude=("author",))))
    # friends = fields.Nested(UserUserSchema(many=True)) # 方式一:使用一个外部的图式,可以指点序列化哪些字段
    friends = fields.Nested("self", only=("name",), many=True)  # 方式二:使用自身图式作为外键的方式,并指定序列化的字段
    # friends = fields.Nested(lambda: UserSchema(many=True, only=("name",)), dump_only=True) # 方式二的一种:使用自身图式作为外键的图式,并指定序列化的字段
    # friends = fields.Pluck("self", "name", many=True) # 方式三:使用Pluck字段可以用单个值来替换嵌套的数据。


@app.route("/")
def index():
    try:
        user0 = User(name="南派三叔", email="sanshu@163.com")
        user1 = User(name="刘慈欣", email="sanshu@163.com")
        user2 = User(name="天下霸唱", email="sanshu@163.com")
        blog = Blog(title="盗墓笔记", author=user0)
        res1 = BlogSchema().dump(blog)
        # print(res, type(res))
        print(res1)
        user0.books = [blog]
        user0.friends.append(user1)
        user0.friends.append(user2)
        res2 = UserSchema().dump(user0)
        print(res2)
    except Exception as err:
        print(err)

    return "hello"


if __name__ == '__main__':
    with app.app_context():
        # db.drop_all()
        db.create_all()

    app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
{'author': {'name': '南派三叔', 
'friends': [],
 'created_at': '2022-04-09 14:04:05', 'email': 'sanshu@163.com', 
'books': []}, 
'title': '盗墓笔记'
}

{'name': '南派三叔', 
'friends': [{'name': '刘慈欣'}, {'name': '天下霸唱'}],
 'created_at': '2022-04-09 14:04:05', 'email': 'sanshu@163.com', 
'books': [{'title': '盗墓笔记'}]
}

反序列化

  • 代码
from flask import Flask
from flask_marshmallow import Marshmallow

app = Flask(__name__)

ma = Marshmallow()
# 注册
ma.init_app(app)

# 反序列化
from marshmallow import Schema, fields, validate, ValidationError


class UserSchema(Schema):
    # Str<--->String
    name = fields.Str(validate=validate.Length(min=1))
    permission = fields.Str(validate=validate.OneOf(["read", "write", "admin"]))
    age = fields.Int(validate=validate.Range(min=18, max=40))


@app.route("/")
def index():
    user_data = {"name": "Ronnie", "age": 18, "permission": "admin"}
    schema = UserSchema()
    result = schema.load(user_data)
    print(result, type(result))  # => <User: 'Ronnie'>
    return "hello"


if __name__ == '__main__':
    app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
{'age': 18, 'name': 'Ronnie', 'permission': 'admin'}

反序列化时转换/忽略部分数据

class UserSchema(Schema):
    name = fields.String(required=True)
    age = fields.Integer(required=True)

@app.route("/")
def index():
	result = UserSchema().load({"age": 42}, partial=("name",))
	print(result)  # => {'age': 42}
    return "ok"

设置字段只在序列化或反序列化阶段才启用

class UserSchema(Schema):
    name = fields.Str()
    # password is 
    password = fields.Str(load_only=True) # 相当于只写字段 "write-only"
    created_time = fields.DateTime(dump_only=True) # 相当于只读字段 "read-only"

反序列化阶段的钩子方法

post_dump([fn,pass_many,pass_original]) 注册要在序列化对象后调用的方法,它会在对象序列化后被调用。
post_load([fn,pass_many,pass_original]) 注册反序列化对象后要调用的方法,它会在验证数据之后被调用。

pre_dump([fn,pass_many]) 注册要在序列化对象之前调用的方法,它会在序列化对象之前被调用。
pre_load([fn,pass_many]) 在反序列化对象之前,注册要调用的方法,它会在验证数据之前调用。

案例

from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,post_dump,post_load,pre_dump,pre_load
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)

ma = Marshmallow()
ma.init_app(app)

class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(255), index=True, comment="用户名")
    age = db.Column(db.Integer, comment="年龄")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(20), comment="手机号")
    created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.name)

class UserSchema(Schema):
    name = fields.String(validate=validate.Length(min=1))
    age = fields.Integer(required=True)
    password = fields.Str(load_only=True) # 相当于只写字段 "write-only"
    # created_time = fields.DateTime(dump_only=True) # 相当于只读字段 "read-only"
    created_time = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
    mobile = fields.String()

    @pre_load
    def pre_load(self,data,**kwargs):
        """反序列化的前置钩子,会在数据验证之前执行"""
        data["created_time"] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        return data

    @post_load
    def post_load(self,data,**kwargs):
        """反序列化钩子方法"""
        data["password"] = generate_password_hash(data["password"])
        return User(**data)

    @post_dump
    def post_dump(self,data,**kwargs):
        """序列化钩子方法"""
        data["number"] = 1000
        data["mobile"] = data["mobile"][:3]+"****"+data["mobile"][-4:]
        return data

@app.route("/")
def index():
    user_data = {"name": "小明", "age": 20,"password":"123456","mobile":"13312345678"}  # 报错
    us = UserSchema()
    # 反序列化
    instance = us.load(user_data)
    print(instance) # <User: 小明>
    print(instance.created_time) # <User: 小明>

    # 序列化
    data = us.dump(instance)
    print(data)
    return "hello"

if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0",port=5999)

反序列化阶段对数据进行验证

基于内置验证器进行数据验证

内置验证器描述
validate.Email(*, error)邮箱验证
validate.Equal(comparable, *, error)判断值是否相等
validate.Length(min, max, *, equal, error)值长度/大小验证
validate.OneOf(choices, labels, *, error)选项验证
validate.Range([min, max])范围验证
validate.Regexp(regex, bytes, Pattern][, flags])正则验证
validate.URL(*, relative, schemes, Set[str]]] = None, …)验证是否为URL

 案例:内置验证器主要写在字段选项中,代码:

from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,post_dump,post_load,pre_dump,pre_load
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)

ma = Marshmallow()
ma.init_app(app)

class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(255), index=True, comment="用户名")
    email = db.String(db.String(255))
    age = db.Column(db.Integer, comment="年龄")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(20), comment="手机号")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.name)

class UserSchema(Schema):
    name = fields.String(validate=validate.Length(min=1))
    age = fields.Integer(required=True,validate=validate.Range(min=16,max=100))
    email = fields.String(validate=validate.Email())
    password = fields.Str(load_only=True,validate=validate.Length(min=6,max=16)) # 相当于只写字段 "write-only"
    mobile = fields.String(validate=validate.Regexp("^1[3-9]\d{9}$",error="手机号格式不正确!"))

@app.route("/")
def index():
    user_data = {"email":"xiaoming@qq.com","name": "小明", "age": 20,"password":"123456","mobile":"13312345678"}  # 报错
    us = UserSchema()
    # 反序列化
    instance = us.load(user_data)
    print(instance)
    return "hello"

if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0",port=5999)

自定义验证方法

通过context或者构造器实例对象进行参数传递

import random
from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,validates,validates_schema,ValidationError,post_load,pre_load
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)

ma = Marshmallow()
ma.init_app(app)

class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(255), index=True, comment="用户名")
    email = db.String(db.String(255))
    age = db.Column(db.Integer, comment="年龄")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(20), comment="手机号")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.name)

class UserSchema(Schema):
    name = fields.String()
    age = fields.Integer()
    email = fields.String()
    password = fields.Str() # 密码
    password2 = fields.String() # 确认密码
    mobile = fields.String(validate=validate.Regexp("^1[3-9]\d{9}$",error="手机号格式不正确!"))

    # 针对单个指定字段的值进行验证
    @validates("mobile")
    def validate_mobile(self,mobile):
        if(mobile == "13312345678"):
            raise ValidationError("手机号已经被注册!!")
        return mobile

    # 针对多个字段的验证
    @validates_schema
    def validate(self,data,**kwargs):
        if(data["password"] != data["password2"]):
            # 注意:验证失败以后,一定是raise抛出异常!!!不能是return!!!!
            raise ValidationError(field_name="password2",message="密码和确认密码不一致!")
        return data

    @post_load
    def post_load(self,data,**kwargs):
        """反序列化验证后的钩子方法"""
        print("num=%s" % self.num)
        print(self.context)
        del data["password2"] # 删除掉不必要的字段
        return User(**data)

@app.route("/")
def index():
    user_data = {"email":"xiaoming@qq.com","name": "小明", "age": 20,"password":"123456","mobile":"13312345671","password2": "123456"}

    num = random.randint(1,100)
    # 如果将来在开发中有部分数据需要传递到构造器中进行调用,可以在实例化构造器时通过context传递参数进行,在构造器内部通过self.context调用
    us = UserSchema(context={"num":num})
    # 如果将来在开发中有部分数据需要传递到构造器中进行调用,可以作为构造器对象的属性进行传递
    us.num = num
    # 反序列化
    instance = us.load(user_data)
    print(instance)
    return "hello"

if __name__ == '__main__':
    app.run(debug=True,host="0.0.0.0",port=5999)

6. 模型构造器

官方文档:

GitHub - marshmallow-code/marshmallow-sqlalchemy: SQLAlchemy integration with marshmallowhttps://github.com/marshmallow-code/marshmallow-sqlalchemy

marshmallow-sqlalchemy — marshmallow-sqlalchemy 0.28.0 documentationhttps://marshmallow-sqlalchemy.readthedocs.io/en/latest/

  • 注意:flask_marshmallow在0.12.0版本以后已经移除了ModelSchema和TableSchema这两个模型构造器类,官方转而推荐了使用SQLAlchemyAutoSchema和SQLAlchemySchema这2个类,前后两者用法类似。
  • 模型构造器实际上是Schema的子类,所以前面所学习的自定义构造器字段,验证器,验证方法,钩子方法等等都可以写进来一起使用。

基于SQLAlchemySchema创建模型构造器

from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)

ma = Marshmallow()
ma.init_app(app)

class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(255), nullable=False, index=True, comment="用户名")
    email = db.String(db.String(255))
    age = db.Column(db.Integer, comment="年龄")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(20), comment="手机号")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.name)

# 用法1:通过SQLAlchemySchema创建构造器,通过auto从模型中提取字段类型和选项
from marshmallow_sqlalchemy import SQLAlchemySchema,auto_field
from marshmallow import fields,validate
class UserSchema(SQLAlchemySchema):
    """模型构造器"""
    id = auto_field()
    name = auto_field()
    password = auto_field()
    # auto_field在使用过程中,除了可以复制模型对应字段的信息和数据类型以外,我们也可以增加补充说明
    mobile = auto_field(required=True,validate=validate.Regexp("^1[3-9]\d{9}$"))
    password2 = fields.String()
    class Meta:
        model = User    # 模型类名 table = models.Album.__table__
        load_instance = True   # 反序列化阶段时,直接返回模型对象
        include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理
        include_fk = True  # 序列化阶段是否也一并返回主键

@app.route("/")
def index():
    user_data = {"name": "小明","mobile":"13"}
    us = UserSchema()
    instance = us.load(user_data,session=db.session)
    print(instance)
    return "hello"

if __name__ == '__main__':
    with app.app_context():
        db.drop_all()
        db.create_all()
    app.run(debug=True,host="0.0.0.0",port=5999)

基于SQLAlchemyAutoSchema创建模型构造器(常用)

class 构造器类名(SQLAlchemyAutoSchema):
    class Meta:
        model = 模型类名    # table = models.Album.__table__
        include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理
        include_fk = True # 序序列阶段是否也一并返回主键
        load_instance = True  # 反序列化阶段时,直接返回模型对象
        sqla_session = db.session # 数据库连接会话对象
        # fields= ["id","name"] # 启动的字段列表
        exclude = ["id","name"] # 排除字段列表

案例

from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)

ma = Marshmallow()
ma.init_app(app)

class User(db.Model):
    __tablename__ = "tb_user"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(255), nullable=False, index=True, comment="用户名")
    email = db.String(db.String(255))
    age = db.Column(db.Integer, comment="年龄")
    password = db.Column(db.String(255), comment="登录密码")
    mobile = db.Column(db.String(20), comment="手机号")

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.name)

# 用法1:通过SQLAlchemySchema创建构造器,通过auto从模型中提取字段类型和选项
from marshmallow_sqlalchemy import SQLAlchemySchema,auto_field,SQLAlchemyAutoSchema
from marshmallow import fields,validate

class UserSchema(SQLAlchemyAutoSchema):
    mobile = auto_field(required=True, validate=validate.Regexp("^1[3-9]\d{9}$"))
    password2 = fields.String(required=True)
    class Meta:
        model = User    # 模型类名 table = models.Album.__table__
        load_instance = True   # 反序列化阶段时,直接返回模型对象
        include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理
        include_fk = True  # 序列化阶段是否也一并返回主键
        sqla_session = db.session # 构造器操作数据库的会话对象
        # fields = ["id","name","mobile","password2"] # 构造器启用的字段列表
        exclude = ["id","name"] # 构造器禁用的字段列表

@app.route("/")
def index():
    user_data = {"mobile":"13312341234","password2":"1234546"}
    us = UserSchema()
    instance = us.load(user_data)
    print(instance)
    return "hello"

if __name__ == '__main__':
    with app.app_context():
        db.drop_all()
        db.create_all()
    app.run(debug=True,host="0.0.0.0",port=5999)

### 回答1: Reqrcode-demo(微信扫码登录)是一种方便的登录方式。它是通过微信公众平台的API接口,实现了用户在使用网站时,可以通过微信扫描二维码的方式直接进行登录,无需输入账号密码的繁琐操作,不仅方便了用户,还可以提高网站的用户体验度。另外,由于微信在国内的用户数量众多,使用微信扫码登录还可以吸引更多的用户来使用网站,从而提高网站的用户数量与活跃度。在技术方面,为了实现Reqrcode-demo,我们需要掌握微信公众平台API的使用,以及开发微信网页端的基本技术,并且需要与网站后台进行良好的对接,保持数据的准确性与安全性。总之,Reqrcode-demo是一种现代化、方便快捷的登录方式,值得网站开发者去尝试使用。 ### 回答2: Reqrcode-demo是一个基于QR码技术的示例项目,旨在演示如何使用QR码技术实现业务功能。该项目中的QR码可以被扫描,用于获取产品信息、支付、结算、预约等操作。 在该项目中,QR码作为一种快速、安全、便捷的交互方式被广泛应用。通过扫描QR码,可以快速获取所需的信息,减少人工操作的时间和难度,提高服务效率和用户体验。 此外,Reqrcode-demo还集成了一些其他的技术,例如加密算法、安全认证、数据存储等,以保障交互过程的安全性和稳定性,并提供更为完整的功能服务。该项目可作为QR码技术在各行业中应用的参考和借鉴,同时也为开发者提供了学习和实践的机会。 随着QR码技术的不断发展和普及,它将会在更多的领域得到应用,为各行业和用户带来更加便捷、高效、安全的交互方式。 ### 回答3: ReqRode-Demo是一个使用Python编程语言和Flask框架实现的简单RESTful风格的API。它是一个用于演示和教学的项目,旨在帮助初学者理解和学习如何构建和使用RESTful API。 ReqRode-Demo提供了一些基本的API接口,例如获取用户列表、获取单个用户信息、添加新用户、更新现有用户等。这些API使用HTTP协议传输数据,并且可以使用curl等工具进行测试。 ReqRode-Demo的代码结构简单明了,易于阅读和理解。它使用了一些流行的Python库和技术,如Flask、Sqlalchemy、marshmallow等,使得编写代码变得更加简单和高效。此外,它还提供了一些有用的代码注释,以帮助初学者更好地理解API接口的实现原理。 总之,ReqRode-Demo是一个非常有用的资源,它可以帮助初学者更好地了解和学习RESTful API的编写和使用。通过学习ReqRode-Demo的代码,初学者可以了解Flask框架的基本使用方法、RESTful API的设计原则和实现方法,以及如何使用Python和相关库来构建功能强大的API接口。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑猪去兜风z1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值