Flask-Security - 应用程序上下文问题 - Peewee
Flask-Security - Application Context Issue - Peewee
我正在努力扩展我的烧瓶技能,并参与了 treehouse flask 社交网络项目并让它运行起来。我现在正在尝试更改设置并允许社交登录 我已经从普通 bcrypt 转移到 flask-security,因为这是 flask-social 的要求。我有单独的应用程序和模型文件,当我尝试使用 utils.encrypt_password()
函数时,我 运行 变成了 RuntimeError: working outside of application context
,它抛出了错误。我可以通过执行 from app import app
来消除错误,然后它指出我的数据库不是模块的属性。
我完全困惑我已经用谷歌搜索了这个问题,但人们的建议总是出错,想知道是否有人可以解释我做错了什么。这是一个 link 我认为可能相似但我不理解我的代码的问题。我在下面发布了我的代码,向您展示我的用户模型和我的 app.py 的上半部分,因为这是堆栈跟踪中的两个部分。
Models.py
import datetime
#from app import app
from flask.ext.login import UserMixin
from flask.ext.security import Security, RoleMixin, utils
from peewee import *
DATABASE = SqliteDatabase('social.db')
#DATABASE = SqliteDatabase(None)
class User(UserMixin, Model):
username = CharField(unique=True)
email = CharField(unique=True)
password = CharField(max_length=100)
joined_at = DateTimeField(default=datetime.datetime.now)
is_admin = BooleanField(default=False)
class Meta:
database = DATABASE
order_by = ('-joined_at',)
def get_posts(self):
return Post.select().where(Post.user == self)
def get_stream(self):
return Post.select().where(
(Post.user << self.following()) |
(Post.user == self))
def following(self):
return (
User.select().join(
Relationship, on=Relationship.to_user
).where(
Relationship.from_user == self
)
)
def followers(self):
return (
User.select().join(
Relationship, on=Relationship.from_user
).where(
Relationship.to_user == self
)
)
@classmethod
def create_user(cls, username, email, password, admin=False):
try:
with DATABASE.transaction():
cls.create(
username=username,
email=email,
password=utils.encrypt_password(password),
is_admin=admin)
except IntegrityError:
raise ValueError("User already exists")
def initialise():
#DATABASE.init_app(app)
DATABASE.connect()
DATABASE.create_tables([User, Post, Relationship, Role, UserRoles, Connection], safe=True)
DATABASE.close()
app.py
from flask import (Flask, g, render_template, flash, redirect, url_for, abort, session, request )
from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user
from flask.ext.social import Social, PeeweeConnectionDatastore
from flask.ext.security import PeeweeUserDatastore, Security
from flask.ext.social.utils import get_provider_or_404
from flask.ext.social.views import connect_handler
from peewee import *
import forms
import models
DEBUG = True
PORT = 8000
HOST = '0.0.0.0'
app = Flask(__name__)
app.secret_key = 'tfdghsf3wquhivfcdsz5.5432jkicdsahuihuj7564jinjnf'
app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
app.config['SECURITY_PASSWORD_SALT'] = '1b3kxc8s9fdsa9431vbgvhui43212ijkdrdwui'
app.config['SOCIAL_GOOGLE'] = {
'consumer_key': '1048991051512-6k0vianfkdece33tool0el7pg72h5lku.apps.googleusercontent.com',
'consumer_secret': 'kDyeeetXqIEq7G9LfGfozLH9'
}
DATABASE = SqliteDatabase('social.db')
app.config['SECURITY_POST_LOGIN'] = '/profile'
user_datastore = PeeweeUserDatastore(models.DATABASE, models.User, models.Role, models.UserRoles)
social_datastore = PeeweeConnectionDatastore(models.DATABASE, models.Connection)
security = Security(app, user_datastore)
social = Social(app, social_datastore)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
编辑:
在进一步研究这个问题之后,它似乎是 flask-security 的问题,因为我在我的 main app.py 中实现了一个测试函数,并且两个给出了相同的运行时错误。
这个问题的答案其实就在我创建用户的位置。我把它留在了我的程序运行代码的主要部分,下面显示了这一点,看起来它脱离了上下文我将我的默认用户创建移动到一个带有 @app.before_first_request
装饰器的函数,它现在可以工作了。
if __name__ == '__main__':
try:
models.User.create_user(
username='BenBrown',
email='ben@aperturedigital.uk',
password='password',
admin=True
)
except ValueError:
pass
app.run(debug=DEBUG, host=HOST, port=PORT)
我正在努力扩展我的烧瓶技能,并参与了 treehouse flask 社交网络项目并让它运行起来。我现在正在尝试更改设置并允许社交登录 我已经从普通 bcrypt 转移到 flask-security,因为这是 flask-social 的要求。我有单独的应用程序和模型文件,当我尝试使用 utils.encrypt_password()
函数时,我 运行 变成了 RuntimeError: working outside of application context
,它抛出了错误。我可以通过执行 from app import app
来消除错误,然后它指出我的数据库不是模块的属性。
我完全困惑我已经用谷歌搜索了这个问题,但人们的建议总是出错,想知道是否有人可以解释我做错了什么。这是一个 link 我认为可能相似但我不理解我的代码的问题。我在下面发布了我的代码,向您展示我的用户模型和我的 app.py 的上半部分,因为这是堆栈跟踪中的两个部分。
Models.py
import datetime
#from app import app
from flask.ext.login import UserMixin
from flask.ext.security import Security, RoleMixin, utils
from peewee import *
DATABASE = SqliteDatabase('social.db')
#DATABASE = SqliteDatabase(None)
class User(UserMixin, Model):
username = CharField(unique=True)
email = CharField(unique=True)
password = CharField(max_length=100)
joined_at = DateTimeField(default=datetime.datetime.now)
is_admin = BooleanField(default=False)
class Meta:
database = DATABASE
order_by = ('-joined_at',)
def get_posts(self):
return Post.select().where(Post.user == self)
def get_stream(self):
return Post.select().where(
(Post.user << self.following()) |
(Post.user == self))
def following(self):
return (
User.select().join(
Relationship, on=Relationship.to_user
).where(
Relationship.from_user == self
)
)
def followers(self):
return (
User.select().join(
Relationship, on=Relationship.from_user
).where(
Relationship.to_user == self
)
)
@classmethod
def create_user(cls, username, email, password, admin=False):
try:
with DATABASE.transaction():
cls.create(
username=username,
email=email,
password=utils.encrypt_password(password),
is_admin=admin)
except IntegrityError:
raise ValueError("User already exists")
def initialise():
#DATABASE.init_app(app)
DATABASE.connect()
DATABASE.create_tables([User, Post, Relationship, Role, UserRoles, Connection], safe=True)
DATABASE.close()
app.py
from flask import (Flask, g, render_template, flash, redirect, url_for, abort, session, request )
from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user
from flask.ext.social import Social, PeeweeConnectionDatastore
from flask.ext.security import PeeweeUserDatastore, Security
from flask.ext.social.utils import get_provider_or_404
from flask.ext.social.views import connect_handler
from peewee import *
import forms
import models
DEBUG = True
PORT = 8000
HOST = '0.0.0.0'
app = Flask(__name__)
app.secret_key = 'tfdghsf3wquhivfcdsz5.5432jkicdsahuihuj7564jinjnf'
app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
app.config['SECURITY_PASSWORD_SALT'] = '1b3kxc8s9fdsa9431vbgvhui43212ijkdrdwui'
app.config['SOCIAL_GOOGLE'] = {
'consumer_key': '1048991051512-6k0vianfkdece33tool0el7pg72h5lku.apps.googleusercontent.com',
'consumer_secret': 'kDyeeetXqIEq7G9LfGfozLH9'
}
DATABASE = SqliteDatabase('social.db')
app.config['SECURITY_POST_LOGIN'] = '/profile'
user_datastore = PeeweeUserDatastore(models.DATABASE, models.User, models.Role, models.UserRoles)
social_datastore = PeeweeConnectionDatastore(models.DATABASE, models.Connection)
security = Security(app, user_datastore)
social = Social(app, social_datastore)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
编辑: 在进一步研究这个问题之后,它似乎是 flask-security 的问题,因为我在我的 main app.py 中实现了一个测试函数,并且两个给出了相同的运行时错误。
这个问题的答案其实就在我创建用户的位置。我把它留在了我的程序运行代码的主要部分,下面显示了这一点,看起来它脱离了上下文我将我的默认用户创建移动到一个带有 @app.before_first_request
装饰器的函数,它现在可以工作了。
if __name__ == '__main__':
try:
models.User.create_user(
username='BenBrown',
email='ben@aperturedigital.uk',
password='password',
admin=True
)
except ValueError:
pass
app.run(debug=DEBUG, host=HOST, port=PORT)