我有一个我想要初始化的模型,例如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.
答案 0 :(得分:0)
以下是我对你要做的事情的解释。您希望创建一个静态方法,将给定的字符串密码转换为哈希密码。显然python的hash
不是密码散列函数,所以我建议使用其他更一致和可靠的东西。可以在应用程序内的User
模型初始化期间使用此散列方法。这意味着每次使用用户名,电子邮件和密码创建用户时,该密码在成为后续User
对象的属性之前首先进行哈希处理。请看下面的插图:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
password = db.Column(db.String(36))
def __init__(self, username, email, password):
self.username = username
self.email = email
self.password = self.generate_pwd_hash(password)
@staticmethod
def generate_pwd_hash(pwd):
"""
This is where you define how
to hash the user's password.
"""
return str(hash(pwd)) # This is, of course, not the way to hash a password
db.create_all()
user = User(username='george',
email='george@example.com',
password='whatever')
try:
db.session.add(user)
db.session.commit()
except:
print("This username must already exist.")