【问题标题】:Mongoengine AttributeErrorMongoengine 属性错误
【发布时间】:2016-07-14 00:27:21
【问题描述】:

我正在尝试使用 Flask-Mongoengine 和 Flask-Login 为应用程序编写授权代码。我收到了这个奇怪的错误:

File "/usr/lib/python3.5/site-packages/mongoengine/base/document.py", line 188, in __setattr__
    super(BaseDocument, self).__setattr__(name, value)
  File "/usr/lib/python3.5/site-packages/mongoengine/base/fields.py", line 132, in __set__
    if instance._initialised:
AttributeError: _initialised

我的models.py:

from app import app, db
from flask.ext.login import LoginManager


login_manager = LoginManager()
login_manager.init_app(app)


class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_lenght=40, required=True)
    last_name = db.StringField(max_lenght=40, required=True)
    password = db.StringField(required=True)

    def __init__(self, email, first_name, last_name, password):
        self.email = email
        self.first_name = first_name
        self.last_name = last_name
        self.password = password

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

   def get_id(self):
        return self.email

我试过超班,但没有帮助。

https://github.com/MongoEngine/flask-mongoengine/issues/156

【问题讨论】:

  • 您对此有任何更新或修复吗?

标签: python flask mongoengine flask-mongoengine


【解决方案1】:

Mongoengine 不需要你定义一个 __init__。

class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_lenght=40, required=True)
    last_name = db.StringField(max_lenght=40, required=True)
    password = db.StringField(required=True)

    def clean(self):
        # clean will be called when you call .save()
        # You can do whatever you'd like to clean data before save
        self.password = str(self.password)

那么你要做的就是

user = User(email='email@gmail', first_name='hello', last_name='there', password=2342143213)
user.save()
print(user.id)

【讨论】:

    【解决方案2】:

    解决这个问题,需要像这样调用超类的构造函数

    class User(db.Document):
        email = db.StringField(required=True)
        first_name = db.StringField(max_lenght=40, required=True)
        last_name = db.StringField(max_lenght=40, required=True)
        password = db.StringField(required=True)
    
        def __init__(self, email, first_name, last_name, password, *args, **kwargs):
            super(User, self).__init__(*args, **kwargs)
            self.email = email
            self.first_name = first_name
            self.last_name = last_name
            self.password = password
    
        def is_authenticated(self):
            return True
    
        def is_active(self):
            return True
    
        def is_anonymous(self):
            return False
    
       def get_id(self):
            return self.email
    

    【讨论】:

      【解决方案3】:

      未来的读者应该知道,clean()每个 save() 调用之前被调用,所以如果它用于对模型中的密码字段进行哈希处理,例如:

      def clean(self):
          self.password = bcrypt.generate_password_hash(self.password).decode('utf-8')
      

      密码将不断被覆盖,这是不希望的。一种解决方法是使用附加字段,例如:password_hashed = db.BooleanField(default=False)

      def clean(self):
          if not self.password_hashed:
              self.password        = bcrypt.generate_password_hash(self.password).decode('utf-8')
              self.password_hashed = True
      

      【讨论】:

        【解决方案4】:

        Super Class还没有创建,你必须调用super,如下所示;

        def __init__(self, email, first_name, last_name, password):
            ***super().__init__()***
            self.email = email
            self.first_name = first_name
            self.last_name = last_name
            self.password = password
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-13
          • 1970-01-01
          相关资源
          最近更新 更多