烧瓶ImportError

时间:2019-01-05 22:32:21

标签: python flask

一般来说,我会先使用Flask和python。我正在尝试使用Flask-Admin构建一个非常基本的应用程序来构建“模型视图”页面。

Flask和Flask-Admin中的所有代码示例均应按预期运行,并且ModelView可以在我的数据库上运行基本CRUD。

但是,当我使用单独的models.py文件(来自this tutorial)时,出现了问题。

app.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///database/db.db"
app.config['FLASK_ADMIN_SWATCH'] = 'flatly'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

from models import *

class PostView(ModelView):
    edit_modal = True

admin = Admin(app, name='ProjectX', template_mode='bootstrap3')
admin.add_view(PostView(Post, db.session))
if __name__ == '__main__':
    app.run()

models.py

from app import db

class Post(db.Model):
    __tablename__ = 'post'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), unique=True, nullable=False)
    text = db.Column(db.String(255), unique=False, nullable=False)

    def __repr__(self):
    return '<Post {}>'.format(self.title)

运行python app.py会得到:

Traceback (most recent call last):
  File "app.py", line 12, in <module>
    from models import *
  File "/Users/me/Sites/projectx/models.py", line 1, in <module>
    from app import db
  File "/Users/me/Sites/projectx/app.py", line 18, in <module>
    admin.add_view(PostView(Post, db.session))
NameError: name 'Post' is not defined

当我将from models import *更改为from models import Post时,会得到

Traceback (most recent call last):
  File "app.py", line 12, in <module>
    from models import Post
  File "/Users/me/Sites/projectx/models.py", line 1, in <module>
    from app import db
  File "/Users/me/Sites/projectx/app.py", line 12, in <module>
    from models import Post
ImportError: cannot import name 'Post'

在我看来db中没有models.py吗?循环导入是否有问题?如果是,该如何解决?

编辑我可能在虚拟环境中搞砸了一些东西(我想我同时运行了pipenv和autoenv),并且对pip / python2 / python3有些困惑。但是我怀疑这与问题有关。该应用程序肯定可以在3.6.5上运行

1 个答案:

答案 0 :(得分:1)

您正在努力解决“循环导入问题”。在这种情况下,就是这样。

Python开始解析/评估app.py。中途,它会找到from models import *(或您尝试过的其他变体之一)。

app.py的解析/求值被暂时中止,以从models中提取符号。

Python开始解析/评估models.py,并立即遇到from app import db

出于某种令人费解的(但明智的)原因,Python随后想要完成app.py的解析/求值,但是当它完成时,它遇到了对Post的引用,但尚未引用之所以被定义,是因为models.py的解析/求值已暂停。然后,Python引发一个NameError

我知道解决此问题的最简单方法是创建一个单独的views.py,看起来像

from app import admin, db
from models import Post
from flask_admin.contrib.sqla import ModelView

class PostView(ModelView):
    edit_modal = True
admin.add_view(PostView(Post, db.session)

然后在导入app.py后在models的末尾导入它。