有没有办法通过 mixin 设置 peewee 字段?

Posted

技术标签:

【中文标题】有没有办法通过 mixin 设置 peewee 字段?【英文标题】:is there a way to set peewee fields via a mixin? 【发布时间】:2020-02-17 09:06:15 【问题描述】:

我正在尝试设置一组可重用的数据模型,我可以将它们包含在多个应用程序中,类似这样(我在这里使用用户作为示例,但实际的是 @987654321 的 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 似乎没有正确处理它的字段:它们最终都作为未绑定的实例而不会保存在数据库中。

我的问题:是否有一种“官方方式”可以在 peewee 中创建可重用的模型 mixinswith fields

我见过其他项目(例如 flask-login)使用 mixins,但这些通常是附加函数,如本例中的 set_password,而不是定义字段本身的函数。


我有一些潜在的替代解决方案,例如

在共享文件中定义模型本身,而不是 mixins,并为每个 models.py 条目分别覆盖它们的 .Meta.database 只定义mixin中的其他函数;让字段每次在models.py中单独定义 使用共享代码作为文件来复制粘贴,而不是直接使用importing。

但是可能有一些更清洁的方法来做到这一点?

【问题讨论】:

【参考方案1】:

这是一个简单的例子:

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 的顺序。

【讨论】:

以上是关于有没有办法通过 mixin 设置 peewee 字段?的主要内容,如果未能解决你的问题,请参考以下文章

在Sass中将变量设置为@mixin?

Vue.js / Mixins - 有没有办法在 vue 组件之外获取全局 mixin-object?

Flask peewee AttributeError:“ModelSelect”对象没有属性“_meta”

有没有办法在 jquery animate 中使用 scss mixin?

有没有办法在运行时通过程序识别代码文件中的保留字?

peewee中创建自己的Field