如何处理 Marshmallow 模式中的 Flask_SQLAlchemy 模型方法?
How to handle Flask_SQLAlchemy models methods in Marshmallow schemas?
我有几个Flask_SQLAlchemy数据模型及其方法如下:
class User(db.Model):
__table_args__ = {'extend_existing': True}
id = db.Column('id',db.Integer , primary_key=True)
username = db.Column('username', db.String(), unique=False , index=True)
password = db.Column('password' , db.String())
email = db.Column('email',db.String(),unique=True , index=True)
role = db.Column('role', db.Integer(), default=0)
account_state = db.Column('account_state', db.Integer(), default=1)
karma = db.relationship('Karma', backref='user', lazy='dynamic', cascade="all, delete-orphan")
registered_on = db.Column('registered_on' , db.DateTime(timezone=True), server_default=func.now())
followed = db.relationship('Follow',
foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'),
lazy='dynamic', cascade='all, delete-orphan')
followers = db.relationship('Follow', foreign_keys=[Follow.followed_id],
backref=db.backref('followed', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')
def to_dict(self):
data = {
'id': self.id,
'username': self.username,
'is_admin': self.is_admin(),
'followers_count': self.followers_count(),
'followed_count': self.followed_count(),
'has_karma': self.has_karma(),
'karma_count': self.karma_count(),
'registered_on': self.registered_on,
}
return data
def is_admin(self):
if self.role == 1:
return True
return False
def load_karma(self):
karma = self.karma.filter_by(user_id=self.id).first()
return karma
def has_karma(self):
karma = self.load_karma()
if not karma:
return False
if karma:
return True
return False
def karma_count(self):
karma = self.load_karma()
if karma:
return karma.number
return 0
def followers_count(self):
return self.followers.count()
def followed_count(self):
return self.followed.count()
class Karma(db.Model):
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
last_karma_date = db.Column(db.DateTime, default=datetime.utcnow)
class Follow(db.Model):
__tablename__ = 'follows'
__table_args__ = {'extend_existing': True}
follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
followed_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
state = db.Column(db.Integer, default=0)
date_followed = db.Column(db.DateTime, default=datetime.utcnow)
如您在用户 class 中所见,我有一些方法,其中之一是 to_dict(),我将其用于 return JSON 数据我的 API 端点,但现在我切换到 Marshmallow 以自动序列化我的模型,我无法理解如何序列化我的用户模型的数据,例如 returns,如 has_karma () 和 karma_count()。我去过官方文档和许多关于 Whosebug 的在线文章和问题,但还没有。到目前为止,这是我的用户模式:
from marshmallow import Schema, fields, ValidationError
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
fullname = fields.Str()
registered_on = fields.DateTime(dump_only=True)
如何像 to_dict() 那样序列化我的方法的 returned 数据?
您必须将方法更改为属性。您可以使用装饰器 @property
.
轻松完成此操作
一个最小的工作示例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from marshmallow import Schema, fields
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column('id', db.Integer, primary_key=True)
username = db.Column('username', db.String(), unique=False, index=True)
@property
def has_karma(self):
return True
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
has_karma = fields.Boolean()
@app.route("/")
def home():
return UserSchema().dump(User(id=1, username='hi'))
if __name__ == '__main__':
app.run()
输出(如果您 运行 应用并访问 http://127.0.0.1:5000/):
has_karma true
id 1
username "hi"
我有几个Flask_SQLAlchemy数据模型及其方法如下:
class User(db.Model):
__table_args__ = {'extend_existing': True}
id = db.Column('id',db.Integer , primary_key=True)
username = db.Column('username', db.String(), unique=False , index=True)
password = db.Column('password' , db.String())
email = db.Column('email',db.String(),unique=True , index=True)
role = db.Column('role', db.Integer(), default=0)
account_state = db.Column('account_state', db.Integer(), default=1)
karma = db.relationship('Karma', backref='user', lazy='dynamic', cascade="all, delete-orphan")
registered_on = db.Column('registered_on' , db.DateTime(timezone=True), server_default=func.now())
followed = db.relationship('Follow',
foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'),
lazy='dynamic', cascade='all, delete-orphan')
followers = db.relationship('Follow', foreign_keys=[Follow.followed_id],
backref=db.backref('followed', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')
def to_dict(self):
data = {
'id': self.id,
'username': self.username,
'is_admin': self.is_admin(),
'followers_count': self.followers_count(),
'followed_count': self.followed_count(),
'has_karma': self.has_karma(),
'karma_count': self.karma_count(),
'registered_on': self.registered_on,
}
return data
def is_admin(self):
if self.role == 1:
return True
return False
def load_karma(self):
karma = self.karma.filter_by(user_id=self.id).first()
return karma
def has_karma(self):
karma = self.load_karma()
if not karma:
return False
if karma:
return True
return False
def karma_count(self):
karma = self.load_karma()
if karma:
return karma.number
return 0
def followers_count(self):
return self.followers.count()
def followed_count(self):
return self.followed.count()
class Karma(db.Model):
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
last_karma_date = db.Column(db.DateTime, default=datetime.utcnow)
class Follow(db.Model):
__tablename__ = 'follows'
__table_args__ = {'extend_existing': True}
follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
followed_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
state = db.Column(db.Integer, default=0)
date_followed = db.Column(db.DateTime, default=datetime.utcnow)
如您在用户 class 中所见,我有一些方法,其中之一是 to_dict(),我将其用于 return JSON 数据我的 API 端点,但现在我切换到 Marshmallow 以自动序列化我的模型,我无法理解如何序列化我的用户模型的数据,例如 returns,如 has_karma () 和 karma_count()。我去过官方文档和许多关于 Whosebug 的在线文章和问题,但还没有。到目前为止,这是我的用户模式:
from marshmallow import Schema, fields, ValidationError
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
fullname = fields.Str()
registered_on = fields.DateTime(dump_only=True)
如何像 to_dict() 那样序列化我的方法的 returned 数据?
您必须将方法更改为属性。您可以使用装饰器 @property
.
一个最小的工作示例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from marshmallow import Schema, fields
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column('id', db.Integer, primary_key=True)
username = db.Column('username', db.String(), unique=False, index=True)
@property
def has_karma(self):
return True
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
has_karma = fields.Boolean()
@app.route("/")
def home():
return UserSchema().dump(User(id=1, username='hi'))
if __name__ == '__main__':
app.run()
输出(如果您 运行 应用并访问 http://127.0.0.1:5000/):
has_karma true
id 1
username "hi"