Peewee 模型中的 getter 和 setter 方法

mar*_*t1n 3 python peewee

我在 Peewee 中有以下简单模型:

class SiteText(BaseModel):
    url = TextField()
    text = TextField()
    my_counter = IntegerField()

    def get_text_by_url(url):
        d = [s.text for s in SiteText.select(SiteText.url == url)]
        d = d[0] if len(d) > 0 else None
        return d

    def save_text(updates):
        # updates is a dict containing, url, text, my_counter
        SiteText.upsert(**updates)

    def get_outage_counter(url):
        c = [c.my_counter for c in SiteText.select(SiteText.url == url)]
        c = c[0] if len(c) > 0 else None
        return c

    def set_outage_counter(url, counter):
        c = SiteText.get(SiteText.url == url)
        c.counter = counter
        c.save()
Run Code Online (Sandbox Code Playgroud)

然而,为某些属性编写 getter 和 setter 感觉相当奇怪。有没有更Pythonic的方法来做到这一点?例如,我是否应该有一个方法来获取和设置指定 URL 的中断计数器?我是否应该将 getter 和 setter 函数转换为属性(尽管它们会与实际属性发生冲突)。欢迎反馈!

Hip*_*ppo 5

Peewee 的playhouse扩展包括混合属性,这可能正是您正在寻找的。它们基本上是@properties,但经过修改以与 peewee 一起使用。

这是我自己的代码的示例:

from peewee import *
from playhouse import hybrid    # <-- imports the hybrid extension

class User(BaseModel):
    username = CharField()
    _password = CharField()    # <-- note the underscore

    # ... other fields come here ...

    @hybrid.hybrid_property
    def password(self):
        return self._password

    @password.setter
    def set_password(self, plaintext):
        self._password = generate_password_hash(plaintext)
Run Code Online (Sandbox Code Playgroud)

这是为了存储散列密码:因此设置器使用一个函数(generate_password_hash在存储密码之前使用函数 ( ) 来处理密码。

在你的情况下,你可以使用你自己的函数

class SiteText(BaseModel):
    _counter = IntegerField()

    @hybrid.property
    def counter(self):
        # code to process output can come here
        return _counter

    @counter.setter
    def set_counter(self, counter):
        # code to process counter comes here
        self._counter = counter
Run Code Online (Sandbox Code Playgroud)

然后,如果s是一个对象,您可以运行、等SiteData命令。数据将在保存为之前自动使用 getter 和 setter 进行预处理s.counter = 1print s.counter_counter在将数据保存到对象中

最后,我建议您不要save()在 getter 和 setter 中运行。相反,让属性保存在对象中,然后save()手动运行以将它们提交到数据库。否则,您最终可能会不必要地多次访问数据库,或者保存一些您不想要的内容。