Flask 全文搜索学习 导入模块问题

学习《Flask Web开发》,在网上找到一份资料关于FLask的全文检索:
https://blog.miguelgrinberg.c...

我按照上面的步骤对model.py做了乡相应的修改:

from app import app
import flask_whooshalchemy as whooshalchemy

class Post(db.Model):
    __tablename__ = 'posts'
    __searchable__= ['body']
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.Text)
    body_html = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    comments = db.relationship('Comment', backref='post', lazy='dynamic')

    @staticmethod
    def generate_fake(count=100):
        from random import seed, randint
        import forgery_py

        seed()
        user_count = User.query.count()
        for i in range(count):
            u = User.query.offset(randint(0, user_count - 1)).first()
            p = Post(body=forgery_py.lorem_ipsum.sentences(randint(1, 5)),
                    timestamp=forgery_py.date.date(True),
                    author=u)
            db.session.add(p)
            db.session.commit()

    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 
                        'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', 
                        'h1', 'h2', 'h2', 'p']
        target.body_html = bleach.linkify(bleach.clean(
            markdown(value, output_format='html'),
            tags=allowed_tags, strip=True))

db.event.listen(Post.body, 'set', Post.on_changed_body)
whooshalchemy.whoosh_index(app, Post)

也在config.py里做了相应的配置:

WHOOSH_BASE = os.path.join(basedir, 'search.db')

但是进入shell却失败了,显示

ImportError: cannot import name 'app'

网上搜索了一下,有建议是因为在__init__.py中使用了工厂函数的原因,推荐在创建模块导入引用程序。于是我将

from app import app

改为:

from manage import app

但是这样有出现了新的问题

File "/home/lu/桌面/11/flasky/manage.py", line 7, in <module>
    from app.models import User, Role, Permission, Post, Follow, Comment
ImportError: cannot import name 'User'

不知道为什么会这样,希望有了解这部分内容的高手讲解一下!

图片描述

app/__init__.py:

from flask import Flask
from flask_bootstrap import Bootstrap
from flask_mail import Mail
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import config
from flask_pagedown import PageDown
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class


bootstrap = Bootstrap()
mail = Mail()
moment = Moment()
db = SQLAlchemy()
pagedown = PageDown()
photos = UploadSet('photos', IMAGES)

login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'


def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    bootstrap.init_app(app)
    mail.init_app(app)
    moment.init_app(app)
    db.init_app(app)
    login_manager.init_app(app)
    pagedown.init_app(app)




    configure_uploads(app, photos)
    patch_request_class(app)

    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint, url_prefix='/auth')


    return app
阅读 3.3k
1 个回答

题主最好提供app/__init__.py源代码,不然大家只能靠猜了。

我看过这本书,所以按照题主使用了书中的例程源码来猜测一下。ImportError应该是是由于循环导入引起的。你在manage.py中导入了models.py中的模型类,在models.py中又导入了manage.py中定义的app(Flask程序实例)。

另外从意义上来说,使用书中第七章的项目结构,就是为了延迟创建实例的时间,使程序在运行时创建。如果再在程序包中导入,就违背了这个目的。

解决方案的话,之前我在flask中使用celery(celery创建实例需要传入app实例)遇到了同样的循环导入问题,网上(作者本人)建议是在创建celery实例的时候使用create_app直接创建一个实例。但是不知道对于你这个可不可行。如果有好的方案,欢迎提出来大家分享。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题