1

我正在尝试构建一个基础模型类,上面有最常用的沙发视图(主要是那些用于 CRUD 的)。

我不能只将 ViewFields 添加到基类中,因为必须根据模型类名称稍微更改内部的 js 字符串。
这在基类中没有问题,__init__但由于某种原因,ViewField 将无法工作。

通常像这样使用 ViewField 时:

class MyModel(Document):
    only_carrots = ViewField("mymodel", js-string)

然后如果我们运行:

mod = MyModel()
mod.only_carrots 

它将显示:
<ViewDefinition '_design/mymodel/_view/only_carrots'>

但是如果 ViewField 在 期间添加__init__,它看起来像这样:

<flaskext.couchdb.ViewField object at 0x10fe8f190>

在基本模型上运行的代码是这样的:

    for attr_name in dir(self):
        if not attr_name.startswith("_") and attr_name not in ["id", "rev"]:
            attr_val = getattr(self, attr_name)
            if isinstance(attr_val, CouchView):
                vd = ViewField(self.doc_type, attr_val.template.render(self.__dict__), name=attr_name, wrapper=self.__class__)
                setattr(self, attr_name, vd)

CouchView 类是我自己的。它仅用于以元类中的代码无法检测到的方式存储 ViewField 的信息。

Document 类(我的基本模型是它的子类)有一个__metaclass__. 这至少可以完成使 ViewField 工作的部分工作,但我认为我自己的课程已经涵盖了这部分内容。

在这里可以找到 python-couchdb 的源代码:
https ://code.google.com/p/couchdb-python/source/browse/#hg%2Fcouchdb

对于 Flask-CouchDB:
https ://bitbucket.org/leafstorm/flask-couchdb/src

__init__那么,当 ViewField 被添加并因此在元类内部不可用时,如何使 ViewField 工作__new__

非常感谢您的帮助。

4

1 回答 1

0

嗯,我想我想通了。或者至少是一种解决方法。

ViewField 所做的就是使用wrapper由它绑定到的类填充的 -param 来启动 ViewDefinition。

因此,在初始化时执行所有这些操作时,只需调用 ViewDefinition 即可,如下所示:

    def __init__(self, *args, **kwargs):
    if not self.doc_type:
        self.doc_type = self.__class__.__name__
    for attr_name in dir(self):
        if not attr_name.startswith("_") and attr_name not in ["id", "rev"]:
            attr_val = getattr(self, attr_name)
            if isinstance(attr_val, CouchView):
                setattr(self, attr_name, ViewDefinition(self.doc_type, attr_name, attr_val.template.render(self.__dict__), wrapper=self))

当然,现在您必须记住在将模型类添加到管理器之前实例化它们(它带有烧瓶扩展):

user = User()
manager.add_document(user)

这在测试时咬了我。当我这么累的时候必须停止这样做。
出于某种原因,您需要添加_data = {}到您的自定义基类中。我不知道为什么它没有正确设置,但它很容易修复。

于 2013-07-01T13:57:21.093 回答