python - 有没有办法通过 mixin 设置 peewee 字段?
问题描述
我正在尝试设置一组可重用的数据模型,我可以将其包含在多个应用程序中,如下所示(我在这里使用用户作为示例,但实际的是Authlib
库的 peewee 后端):
# mixins.py
class UserMixin(peewee.Model):
username = peewee.CharField()
password = peewee.CharField()
def set_password(self):
# do stuff
...
一旦创建了 mixin,我应该能够像这样导入它,只定义附加字段(默认值已经从 mixin 中获得)
# models.py
db = peewee.SqliteDatabase(config.get('DATABASE_FILE'))
class BaseModel(peewee.model):
class Meta:
database = db
class User(BaseModel, UserMixin):
email = peewee.CharField()
...
我见过人们用SQLAlchemy
, 但是当我用 peewee 使用这个策略时,它似乎没有正确保存字段:
- 如果
UserMixin
继承自peewee.Model
,则表示“无法解析导入层次结构”(可能是因为我们peewee.Model
多次导入) - 如果
UserMixin
只是一个object
,那么 peewee 似乎没有正确处理它的字段:它们最终都作为未绑定的实例并且没有保存在数据库中。
我的问题:是否有一种“官方方式”来创建可重用的模型 mixin与peewee 中的字段?
我见过其他项目(例如flask-login
)使用 mixins,但这些通常set_password
是本示例中的附加功能,而不是定义字段本身的功能。
我有一些潜在的替代解决方案,比如
- 在共享文件中定义模型本身,而不是 mixins,并
.Meta.database
为每个models.py
条目分别覆盖它们 - 只定义mixin中的其他函数;让字段每次都单独定义
models.py
- 使用共享代码作为文件来复制粘贴,而不是
import
直接 ing。
但是可能有一些更清洁的方法可以做到这一点?
解决方案
这是一个简单的例子:
from peewee import *
db = SqliteDatabase(':memory:')
class Base(Model):
class Meta:
database = db
class UserModelMixin(Model):
username = TextField()
class User(UserModelMixin, Base):
pass
print(User._meta.fields)
#{'id': <AutoField: User.id>, 'username': <TextField: User.username>}
我认为问题在于你的 mixin 的顺序。
推荐阅读
- java - 为什么自从 java 9 PhantomReference java doc 声明它专用于 POST-mortem 清理操作,尽管它之前是 PRE-mortem
- elasticsearch - Elasticsearch:“分片分配”是什么意思?
- azure-devops - DevOps 电子邮件的电子邮件过滤器
- javascript - Input type=[number] 在显示时将 float 转换为 int
- python - 将具有很少或没有异常的名称聚类/分组到熊猫中的聚类中
- html - 如何为所有相同的填充制作一组价格
- prolog - 获取一个Prolog类型的所有元素
- java - 'mvnw' 未被识别为内部或外部命令
- asynchronous - 猫鼬中的异步/等待功能
- java - 如何在 java 中正确读取阿拉伯语数据集?