我正在尝试使用最常用的沙发视图构建基础模型类(主要用于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__
无法使用它?
非常感谢您的帮助。
答案 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 = {}
添加到自定义基类。我无法弄清楚为什么它没有正确设置,但它很容易解决。