2016-01-28 2 views
1

Как различается атрибут класса и атрибут экземпляра для классов, расширяющих документ Mongoengine? Все атрибуты выглядят как атрибуты класса, но при создании двух экземпляров эти переменные не используются. Как можно создать атрибуты класса и атрибуты экземпляра с помощью mongoengine?Как различается атрибут класса и атрибут экземпляра для документа Mongoengine?

------ ------ редактировать

class User(Document): 
    email = StringField(required=True) 
    first_name = StringField(max_length=50) 
    last_name = StringField(max_length=50) 

Это документация пример mongoengine дает для определения документа пользователя. Как они определены, они являются атрибутами уровня класса. Однако Document.py и BaseDocument.py заботятся о том, чтобы они не были распространены среди экземпляров Пользователя. Я хочу иметь атрибуты уровня класса, которые совместно используются экземплярами, а также сохраняются в mongodb, когда метод save() вызывается в документе

+1

можете ли вы добавить примерный код, чтобы дополнительно проиллюстрировать ваш вопрос? –

+0

Я думаю, что я понимаю, что вы сомневаетесь в том, что хотите получить общую информацию между документами в mongodb, но она по-прежнему не на 100% понятна. –

ответ

1

Если вы создаете два экземпляра Пользователя и сохраняете их, тогда у вас будет два документа в Коллекция. Если вы хотите, чтобы они оба имеют общую информацию, то есть несколько способов для достижения этой цели:

1. По умолчанию атрибутов

class User(db.Document): 
    email = db.StringField(required=True) 
    first_name = db.StringField(max_length=50) 
    last_name = db.StringField(max_length=50) 
    usertype = db.StringField(default="web user") 


u1 = User(email="[email protected]", first_name="user", last_name="one").save() 
u2 = User(email="[email protected]", first_name="user", last_name="two").save() 

assert u1.usertype == "web user" 
assert u2.usertype == "web user" 

2. внедренных документы

class UserType(db.EmbeddedDocument): 
    role = db.StringField(choices=['Admin','Basic','Guest']) 

class User(db.Document): 
    email = db.StringField(required=True) 
    first_name = db.StringField(max_length=50) 
    last_name = db.StringField(max_length=50) 
    usertype = db.EmbeddedDocumentField(UserType) 


basic = UserType(role="Basic") 
u1 = User(email="[email protected]", first_name="user", last_name="one", usertype=basic).save() 
u2 = User(email="[email protected]", first_name="user", last_name="two", usertype=basic).save() 

assert u1.usertype.role == "Basic" 
assert u2.usertype.role == "Basic" 

- . ссылочные документы

class UserType(db.Document): 
    role = db.StringField(choices=['Admin','Basic','Guest']) 

class User(db.Document): 
    email = db.StringField(required=True) 
    first_name = db.StringField(max_length=50) 
    last_name = db.StringField(max_length=50) 
    usertype = db.ReferenceField(UserType) 


basic = UserType(role="Basic").save() 
u1 = User(email="[email protected]", first_name="user", last_name="one", usertype=basic).save() 
u2 = User(email="[email protected]", first_name="user", last_name="two", usertype=basic).save() 

assert u1.usertype.role == "Basic" 
assert u2.usertype.role == "Basic" 

Когда использовать EmbeddedDocument по сравнению с ReferenceField зависит от on your data model design.

+0

Любая из трех вещей не решает мою цель. Использование атрибутов класса заключается в совместном использовании атрибута между экземплярами этого класса. Но я полагаю, что нет смысла иметь общую переменную в сущности, которая сохраняется. – tunetopj

+0

Целью классов mogoengine 'Document' является сопоставление документов в коллекции с объектами python. Если вам требуется какая-то другая переменная, которая не подходит для вашей модели данных, чтобы ссылаться на нее, вы должны просто использовать простые классы python для этого. –

+0

Могу ли я задать соответствующий вопрос; почему mongoengine решил иметь документы, определенные на уровне класса, а не определяя поля в __init __()? Это будет интуитивно понятным для обычных разработчиков python, а также сделает переход от (или переход на) mongoengine более чистым и легким. – tunetopj