在蓝图Flask中获取mongo实例的正确方法

时间:2018-12-05 09:12:29

标签: python flask flask-pymongo

我在flask应用程序中有3个蓝图,目录结构如下:

main/
   __init__.py
   books/
   users/
   authors/
   apps/

每个包inisde main都是blueprint。 在我的main/__init__.py中,

from flask import Flask
from flask_pymongo import PyMongo

app = Flask(__name__)

from main.users.views import users
from main.admin.views import admin
app.register_blueprint(users, url_prefix='/api/users')

MONGO_HOST = os.environ['MONGO_HOST']
MONGO_PORT = os.environ['MONGO_PORT']

app.config["MONGO_URI"] = "mongodb://{}:{}/".format(MONGO_HOST, MONGO_PORT)
mongo = PyMongo(app)

如何在每个蓝图内访问mongo ?这是在这里使用mongo的正确方法吗? 在official documentation中说不要使用db=Pymongo(app)

1 个答案:

答案 0 :(得分:0)

我想答案对您来说太迟了,但最终还是可以帮上忙。

我通常将数据库行排除在外部文件中,例如database.py。 然后分别在我的应用程序和蓝图中导入 mongo 实例。请考虑以下示例。为了完善和理解,我还添加了对功能有意义的其他元素。

database.py

from flask_pymongo import PyMongo
mongo = PyMongo()

forms.py

from wtforms import Form
from wtforms.fields import BooleanField, PasswordField, StringField
from wtforms.validators import Email, Required

class LoginForm(Form):
    email = StringField('Email', validators=[Required(), Email('Not a valid email address')])
    password = PasswordField('Password',validators=[Required()])
    remember = BooleanField('Remember')

authentication.py

from flask import Blueprint, redirect, render_template, request
from flask_login import LoginManager, UserMixin, current_user, login_user
from werkzeug.security import check_password_hash
from database import mongo
from forms import LoginForm

authentication = Blueprint('authentication', __name__, template_folder='templates')

login_manager = LoginManager()
login_manager.login_view = 'authentication.log_in'

@authentication.route('/login', methods=['GET', 'POST'])
def log_in():
    if (current_user.is_authenticated):
        return redirect(url_for('get_index'))

    login_form = LoginForm(request.form)

    if (request.method == 'POST'):
        if (login_form.validate()):
            user_collection = mongo.db.user
            user = user_collection.find_one({'email':login_form.email.data})

            if (user) and (check_password_hash(user['password'],
                            login_form.password.data)):
                login_user(User(user), login_form.remember)
                return redirect(url_for('get_index'))
            else:
                return render_template('login.html', form=login_form)

    elif (request.method == 'GET'):
        return render_template('login.html', form=login_form)

class User(UserMixin):

    def __init__(self, user):
        super()
        self.id = user['_id']
        self.email = user['email']

    def get(user_id, mongo):
        user_collection = mongo.db.user
        user = user_collection.find_one({'_id':ObjectId(user_id)})
        return User(user)


@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id, mongo)

app.py

from flask import Flask, render_template, request
from flask_login import login_required

from authentication import authentication, login_manager
from database import mongo
from forms import LoginForm

app = Flask(__name__)
app.secret_key = os.urandom(24)

app.config['MONGO_URI'] = 'mongodb:27017/app'
mongo.init_app(app)

app.register_blueprint(authentication)
login_manager.init_app(app)

@app.route('/', methods=['GET'])
@login_required
def get_index():
    if (request.method == 'GET'):
        render_template('index.html')

if __name__ == '__main__':
    app.run(host="0.0.0.0")