如何扩展peewee以使用逻辑删除?

3 投票
1 回答
842 浏览
提问于 2025-04-18 09:55

我在一个项目中使用peewee作为ORM(对象关系映射),想要扩展它来处理逻辑删除。

我在基础模型中添加了一个“deleted”字段,并且对删除操作进行了如下扩展:

@classmethod
def delete(cls, permanently=False):
    if permanently:
        return super(BaseModel, cls).delete()
    else:
        return super(BaseModel, cls).update(deleted=True, modified_at=datetime.datetime.now())

def delete_instance(self, permanently=False, recursive=False, delete_nullable=False):
    if permanently:
        return self.delete(permanently).where(self.pk_expr()).execute()
    else:
        self.deleted = True
        return self.save()

这样做效果很好。不过,当我重写select(选择)操作时遇到了一些问题。

@classmethod
def select(cls, *selection):
    print selection
    return super(BaseModel, cls).select(cls, *selection).where(cls.deleted == False)

在大多数情况下,这样做是有效的,但在某些选择操作中,当查询结果需要使用“IN”关键字进行连接时,就会出现错误:“1241, '操作数应该包含1列'”。

有没有什么建议可以让我正确地重写select,或者绕过这个问题呢?

1 个回答

3

我在我的模型中总是使用一个字段来表示这个模型是否被删除。我不建议重写像 delete、delete_instance 这样的函数,尤其是 select 这个函数。相反,应该创建一个新的接口来处理这些操作。下面是我通常的做法:

class StatusModel(Model):
    status = IntegerField(
        choices=(
            (1, 'Public'),
            (2, 'Private'),
            (3, 'Deleted')),
        default=1)

     @classmethod
     def public(cls):
         return cls.select().where(cls.status == 1)

撰写回答