0

_cls除了使类的名称更短(这会使代码难以阅读)之外,有没有办法在 mongoengine 中使用更短的值?

我一直在寻找这样的东西:

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 是开源的,我可以继续编写代码,但如果您知道更简单的解决方案,我很想听听。

谢谢。

4

2 回答 2

1

在查看了 mongoengine 的源代码后,我和MiniQuark得到了下一个 hack:

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(或者至少在你定义任何子类之前,否则它们将有一个_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()
于 2013-04-06T13:37:22.567 回答
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% 的空间。但我不喜欢它是多么的骇人听闻。

于 2013-04-06T09:52:25.603 回答