Есть ли способ установить поля peewee через миксин? - PullRequest
0 голосов
/ 21 октября 2019

Я пытаюсь настроить многократно используемый набор моделей данных, который я могу включить в несколько приложений, что-то вроде этого (здесь я использую пользователей в качестве примера, но фактическим является peewee backend для * 1001). * library):

# mixins.py

class UserMixin(peewee.Model):
    username = peewee.CharField()
    password = peewee.CharField()

    def set_password(self):
        # do stuff
    ...

После создания этого миксина я смогу импортировать его следующим образом, определяя только дополнительные поля (значения по умолчанию уже будут в миксине)

# 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, похоже, необрабатывать его поля правильно: все они заканчиваются как несвязанные экземпляры и не сохраняются в базе данных.

Мой вопрос: существует ли "официальный способ" создания повторно используемыхмодель mixins с полями в peewee?

Я видел, что другие проекты (например, flask-login) используют миксины, но это, как правило, дополнительные функции, такие как set_password в этом примере, а не те, которые определяют сами поля.


У меня есть несколько возможных альтернативных решений, таких как

  • Определите сами модели, а не миксины, в общем файле и переопределите их .Meta.database отдельно для каждой models.py записи
  • Определите только другие функции в миксине;пусть поля определяются каждый раз отдельно в models.py
  • Используйте общий код как файл для копирования-вставки, а не import непосредственно.

Но, вероятно, естькакой-нибудь более чистый способ сделать это?

1 Ответ

0 голосов
/ 21 октября 2019

Вот простой пример:

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>}

Я думаю, что проблема заключалась в заказе ваших миксинов.

...