除了使类的名称更短(这会使代码难以阅读)之外,有没有办法在mongoengine中使用更短的_cls
值?
我正在寻找这样的事情:
class User(Document):
login = StringField(primary_key = True)
full_name = StringField()
meta = { "short_class_name": "u" }
class StackOverFlowUser(User):
rep = IntField()
meta = { "short_class_name": "s" }
如果存在short_class_name
元属性(但我没有找到它或类似的东西),那么我们可以这样:
{ "_cls" : "s", "_id" : "john",
"full_name" : "John Smith", "rep" : 600 }
而不是:
{ "_cls" : "User.StackOverFlowUser", "_id" : "john",
"full_name" : "John Smith", "rep" : 600 }
在这个例子中,这可以节省大约20%的空间,在某些情况下,甚至可以更大。
我想mongoengine是开源的,我可以继续编码,但如果你知道一个更简单的解决方案,我很乐意听到它。
感谢。
答案 0 :(得分:1)
在查看了mongoengine的源代码后,我在大多数情况下 MiniQuark 得到了下一个黑客:
def hack_document_cls_name(cls, new_name):
cls._class_name = new_name
from mongoengine.base import _document_registry
_document_registry[new_name] = cls
或作为类装饰者:
def hack_document_cls_name(new_name):
def wrapper(cls):
cls._class_name = new_name
from mongoengine.base import _document_registry
_document_registry[new_name] = cls
return cls
return wrapper
除了_class_name
和_document_registry
之外,我们没有其他方法。
如果要重命名一个类,必须在类定义之后立即应用此hack(或者至少在定义任何子类之前应用此hack,否则它们将具有基类类长的_types
属性名称)。例如:
class User(Document):
login = StringField(primary_key = True)
full_name = StringField()
hack_document_cls_name(User, "u")
class StackOverflowUser(User):
rep = IntField()
hack_document_cls_name(StackOverflowUser, "s")
或作为类装饰者:
@hack_document_cls_name("u")
class User(Document):
login = StringField(primary_key = True)
full_name = StringField()
@hack_document_cls_name("s")
class StackOverflowUser(User):
rep = IntField()
答案 1 :(得分:0)
好的,到目前为止,我能想到的最好的就是这个。它有效,但我确信必须有更少的黑客解决方案......
class U(Document): # User
meta = { "collection": "user" }
login = StringField(primary_key = True)
full_name = StringField()
class S(U): # StackOverflowUser
rep = IntField()
User = U; del(U)
StackOverflowUser = S; del(S)
User.__name__ = "User"
StackOverflowUser.__name__ = "StackOverflowUser"
现在我这样做了:
StackOverflowUser.objects.create(login="john", full_name="John Smith", rep=600)
我在user
集合中获取此文档:
{ "_cls" : "U.S", "_id" : "john", "full_name" : "John Smith", "rep" : 600 }
与标准行为相比,这节省了大约20%的空间。但我不喜欢它是多么的黑暗。