2013-06-02 16 views
5

在Mongoengine 0.7.10我的自定義setter屬性,我仍然可以做這樣的事情:Mongoengine 0.8.0斷裂處模型

class User(db.Document): 
    email = db.EmailField(unique=True, required=True) 
    _password = db.StringField(max_length=255, required=True) 

    @property 
    def password(self): 
     return self._password 

    @password.setter 
    def password(self, password): 
     self._password = bcrypt.generate_password_hash(password) 
user = User(email='[email protected]', password='12345') 

然而,上面的代碼斷裂處0.8.0: ValidationError: ValidationError (User:None) (_password.Field is required: ['User'])

看起來,MongoEngine在啓動過程中無法識別我的自定義密碼設置器。我必須手動寫這些來解決它:

user = User(email='[email protected]') 
user.password='12345' 

這可能是由於下面的變化(從Mongonengine 0.8 upgrading notes):

Previously, if you had data the database that wasn’t defined in the Document definition, it would set it as an attribute on the document. This is no longer the case and the data is set only in the document._data dictionary:

我想知道這是有意或爲它是MongoEngine中的一個錯誤?在我的模型中編寫自定義屬性設置器的最佳做法是什麼?

+0

你試過擴展'__init__'嗎? –

+1

@ThomasOrozco你是說像這樣延伸? 'def __init __(self,email,password):當mongoengine從數據庫加載文檔時,Mongoengine會將'_password'傳遞給'User.init()'方法。這會使應用程序崩潰,因爲'__init__'方法不接受'_password'。 – Jiequan

+0

您應該重用已經存在的方法的簽名,可能使用'* args'和'** kwargs'進行擴展。 –

回答

1

這不是一個錯誤 - 它清除了一些其他錯誤,並且是升級文檔中提到的預期操作。但是,這對於這種情況沒有好處!

我想創建密碼哈希的自定義方法會更好。例如:set_password check_password等等

已經有PasswordField實現在過去,這是我的東西會增加額外-mongoengine。

+0

嗨羅斯,我已經看到你的更新有關PasswordField這裏https://github.com/MongoEngine/extras-mongoengine/問題/ 8但仍然無法弄清楚如何使用這個補丁,我使用的是mongoengine 0.8.7,並且還嘗試按照https://github.com/noQ/mongoengine中給出的指令重新安裝,但是當我嘗試使用PasswordField它顯示未定義的錯誤。也檢查了mongoengine.fields,但沒有PasswordField。你能幫我解決嗎? :) – CrazyGeek

4

試試這個代碼:

class User(db.Document): 
    email = db.EmailField(unique=True, required=True) 
    _password = db.StringField(max_length=255, required=True, db_field='password') 

    def __init__(self, *args, **kwargs): 
      db.Document.__init__(self, *args, **kwargs) 

      if 'password' in kwargs: 
       self.password = kwargs['password'] 

    @property 
    def password(self): 
     return self._password 

    @password.setter 
    def password(self, password): 
     self._password = bcrypt.generate_password_hash(password) 
user = User(email='[email protected]', password='12345') 

這對我的作品。

+1

另外如果你想在'db'中將它保存爲'password'而不是'_password',那麼執行'_password = StringField(max_length = 255,required = True,db_field ='password')' –