1

私はフラスコのスキルを拡大することに取り組んでおり、ツリーハウス フラスコ ソーシャル ネットワーク プロジェクトに取り組み、それを機能させました。現在、設定を変更してソーシャルログインを許可して遊んでいます。フラスコソーシャルの要件であるため、プレーンなbcryptからフラスコセキュリティに移行しました。アプリ ファイルとモデル ファイルが別々にありRuntimeError: working outside of application context、関数を使用しようとするとutils.encrypt_password()エラーがスローされます。そうすることでエラーを取り除くことができfrom app import app、データベースがモジュールの属性ではないことが示されます。

問題をグーグルで検索しましたが、誰かが私が間違っていることを説明できるかどうか疑問に思っている人々の提案でエラーが発生し続けています。これは似ていると思われる質問へのリンクですが、コードに関してはわかりません。以下にコードを投稿して、ユーザー モデルと app.py の上半分を示します。これらはスタック トレースにある 2 つの部分です。

モデル.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'

編集: 問題をさらに調べた後、メインの app.py にテスト関数を実装し、2 つが同じランタイム エラーを出したため、flask-security の問題である可能性があるようです。

4

1 に答える 1

0

この質問に対する答えは、実際にはユーザー作成の場所にあります。プログラムがコードを実行するメイン セクションの場所に残していましたが、これは次のように表示されます。コンテキストから外れているように見えます。デフォルトのユーザー作成を@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)
于 2016-02-07T12:41:45.350 に答える