python-couchdb在实例化后将ViewField添加到Model

时间:2013-06-29 19:00:28

标签: python flask couchdb-python

我正在尝试使用最常用的沙发视图构建基础模型类(主要用于CRUD)。

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

通常使用ViewField时:

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

然后如果我们跑:

mod = MyModel()
mod.only_carrots 

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

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

<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时使其工作,因此在元类中__new__无法使用它?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分: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))

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

user = User()
manager.add_document(user)

我在测试时咬了我一下。当我这么累的时候要停止这样做 出于某种原因,您需要将_data = {}添加到自定义基类。我无法弄清楚为什么它没有正确设置,但它很容易解决。