我为Flask-Login创建了一个用户类,如下所示:
{ '-LaAHp3jEK70tWB01-Go':
{ ordered_item_cost: '15',
ordered_item_name: 'bourban-biscuits',
ordered_item_quantity: '1',
ordered_item_total_cost: 15,
ordered_time: '3/17/2019, 4:26:05 PM' },
'-LaAHsjSCNqz8VbxeMgp':
{ ordered_item_cost: '5',
ordered_item_name: 'dark fantasy',
ordered_item_quantity: '1',
ordered_item_total_cost: 5,
ordered_time: '3/17/2019, 4:26:20 PM' } }
,我有一个用户帐户路由,用户可以在其中编辑和删除其帐户。但是,要获取用户并从数据库中更新/删除,我需要使用pymongo代码:
@login_manager.user_loader
def load_user(user_id):
users = mongo.db.users
u = users.find_one({"_id": user_id})
return User(u)
class User(UserMixin):
def __init__(self, user_json):
self.user_json = user_json
def is_authenticated(self):
return True
def is_anonymous(self):
return False
def is_active(self):
return True
def get_id(self):
object_id = self.user_json.get('_id')
return str(object_id)
def get_reset_token(self, expires_sec=3600):
s = Serializer(app.config['SECRET_KEY'], expires_sec)
id = str(self.user_json.get('_id'))
return s.dumps({'user_id': id}).decode('utf-8')
@staticmethod
def verify_reset_token(token):
s = Serializer(app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return None
return load_user(user_id)
或
users = mongo.db.users
user = users.find_one({'_id': user_id})
要从数据库中获取适当的用户,并执行此操作,我需要从当前用户获取ID。 当我尝试使用current_user.get_id()时,出现以下错误:
user = users.find_one({'email': user_email})
并且如果我尝试在current_user周围投射用户(请注意current_user是flask-login属性),则会出现错误:
builtins.AttributeError
AttributeError: 'NoneType' object has no attribute 'get'
Traceback (most recent call last)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/leawhitelaw/enu_group_project/src/app_f/routes.py", line 135, in account
current_user.get_id()
File "/Users/leawhitelaw/enu_group_project/src/app_f/db_classes.py", line 29, in get_id
object_id = self.user_json.get('_id')
AttributeError: 'NoneType' object has no attribute 'get'
令人困惑的是,在get_reset_token函数中,获取_id是有效的,因为当我使用它时,该函数运行得很好。我也尝试过:
builtins.AttributeError
AttributeError: 'User' object has no attribute 'get'
Traceback (most recent call last)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/leawhitelaw/enu_group_project/src/app_f/routes.py", line 126, in account
user.get_id()
File "/Users/leawhitelaw/enu_group_project/src/app_f/db_classes.py", line 29, in get_id
object_id = self.user_json.get('_id')
File "/usr/local/lib/python3.7/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
AttributeError: 'User' object has no attribute 'get'
,其中得到NoneType不可下标或User type不可下标。
我知道User对象与数据库中的用户不同,但是我需要从current_user获取一些信息才能将其连接到数据库中的相应用户。
答案 0 :(得分:1)
默认情况下,此处的User类没有get()
方法,也没有实现支持__getitem__()
或类似访问模式所必需的user["email"]
方法,这是导致错误的根本原因
对get_reset_token()
的调用之所以有效,是因为它对self.user_json.get('_id'))
进行了调用,其中user_json
是包装的字典,它确实支持get和subscribeable访问。
可能的解决方案:
这是部分解决方案,还有其他一些魔术方法可以实现,以使用户的行为更像字典,但这是一个起点。
class User(UserMixin):
...
def get(self, key):
return self.user_json.get(key)
def __getitem__(self, key):
return self.user_json[key]
def __setitem__(self, key, value):
return self.user_json[key] = value
def __delitem__(self, key):
del self.user_json[key]
...
与get_email()
之类的getter方法相比,属性更具Python风格。
class User(UserMixin):
...
@property
def email(self):
return self.user_json["email"]
@email.setter
def email(self, value):
self.user_json["email"] = value
...