【发布时间】:2017-09-01 02:00:25
【问题描述】:
我有一个想要初始化的模型,例如SomeModel(name='george', password='whatever').
在将它提交到数据库之前,我想调用另一个方法(我们称之为gen_password_hash)来创建密码的哈希版本,并将其设置为模型实例的属性。
所以我希望这发生在实例化之后,但在提交到数据库之前。
更新
我想看看是否可以通过在我的模型上定义 __init__ 函数来实现这一点。
def __init__(self, **kwargs):
self.set_pass(kwargs.pop('password'))
super(User, self).__init__(**kwargs)
self.generate_email_address_confirmation_token()
这是我在尝试删除/重新创建表以重置我的应用程序时得到的回溯:
Traceback (most recent call last):
File "main.py", line 7, in <module>
import gg.cli
File "/home/blaine/freelance/myproject/gg/cli/__init__.py", line 183, in <module>
reset_all()
File "/home/blaine/freelance/myproject/gg/cli/__init__.py", line 164, in reset_all
load_test_data()
File "/home/blaine/freelance/myproject/gg/cli/__init__.py", line 51, in load_test_data
admin=True)
File "<string>", line 4, in __init__
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
raise value
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/sqlalchemy/orm/state.py", line 411, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/home/blaine/freelance/myproject/gg/users.py", line 67, in __init__
self.generate_email_address_confirmation_token()
File "/home/blaine/freelance/myproject/gg/users.py", line 71, in generate_email_address_confirmation_token
token.update(self.email_address.encode() + current_app.secret_key + \
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/home/blaine/freelance/myproject/lib/python3.4/site-packages/flask/globals.py", line 51, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in a way. To solve
this set up an application context with app.app_context(). See the
documentation for more information.
【问题讨论】:
-
这取决于
gen_password_hash的定义方式。如果它是在SomeModel类中定义的,那么您应该能够实例化该类,然后在提交之前调用方法.gen_password_hash。但如果它是在模型之外定义的函数,那么您需要类似user = SomeModel(name='george', password='whatever'); user.hashed_pwd = gen_password_hash(user.password); db.session.add(user); db.session.commit()的东西。如果您有第二种情况,还要确保hashed_pwd是您的模型中定义的列。 -
我明白了。这样可行。我希望使用
__init__方便地包装所有这些东西,但我收到错误消息,说我在应用程序上下文之外工作。 -
欢迎分享导致错误的代码,我或这里的其他人将很乐意提供修复。您绝对可以使用 init 来获取密码散列。
-
好的,我已经添加了我尝试的解决方案。
标签: python-3.x sqlalchemy flask-sqlalchemy