【问题标题】:ImportError: No module named viewsImportError:没有名为视图的模块
【发布时间】:2016-09-09 13:15:04
【问题描述】:

我在烧瓶中编写一个 Web 应用程序,显示从 api 中提取的巴士站。

我在 index.html 上有一个表单,用户可以在其中输入停止编号,该编号会在 views.py 中获取,该函数还通过 celery 运行任务以获取 api 数据:

from flask import render_template, request
from app import app

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/stopno', methods=['POST'])
def stopno():
    stopid = request.form['input']
    from app.tasks import apidata
    apidata.delay()
    return render_template('action.html')

这是我的tasks.py:

from celery import Celery
import json
import requests
import time

ac = Celery('tasks', broker='amqp://localhost')

@ac.task(name='tasks.apidata')
def apidata():
    from views import stopno
    api = '*apiurl*:' + str(stopid)
    saveinfo = 'static/stop' + str(stopid)+ '.json'

    r = requests.get(api)
    jsondata = json.loads(r.text)

    with open(saveinfo, 'w') as f:
        json.dump(jsondata, f)

我正在将视图中的 stopno 导入到任务中,因此我可以在 api 中搜索指定的停靠点,当前当用户输入停靠点编号时,action.html 加载正常并显示用户输入的停靠点编号,但没有新文件或数据是为停止号创建的,并且 celery 会抛出错误提示

ImportError: No module named views

我的项目结构是

|____run.py
|____app
| |______init__.py
| |____views.py
| |____tasks.py
| |____static
| | |____json
| |____templates
| | |____action.html
| | |____index.html

【问题讨论】:

  • 试试from app.views import stopno
  • 已经试过了,抛出同样的错误。

标签: python module celery python-import celery-task


【解决方案1】:

您正在尝试进行相对导入,但您没有明确将其设为相对,这可能会或可能不会起作用,并且可能导致意外错误。您应该使您的导入明确地与:

from .views import stopno

这样您就不必担心复制模块的整个路径。

【讨论】:

    【解决方案2】:
    from app.views import stopno
    

    ??

    【讨论】:

    • 有太多叫做“app”的东西在飘。重命名文件夹,或在您的代码中重命名应用程序实例。
    • 虽然我同意您的回答和评论,但为了使其更好,请考虑对其进行解释并删除尾随的问号。
    • 事实上,我最初并不认为这是一个答案......然后我意识到这只是一个低质量的尖刻答案。一些简单的解释有很长的路要走。
    【解决方案3】:

    导入对您不起作用,因为您正在尝试 implicit relative import

    python 2 支持,但 python 3 不支持。

    试试这个:from .views import stopno,这是explicit relative importpython 3 支持它

    如果这不起作用

    尝试从这样的视图中导入所有内容:from .views import *

    永远记住,在python 3 中,import * 仅在模块级别受支持,而不是像这样的内部函数:

    @ac.task(name='tasks.apidata')
    def apidata():
        from .views import *
    

    因此,如果您使用的是:from .views import *,请确保您这样写:

    from celery import Celery
    import json
    import requests
    import time
    from .views import *
    
    ac = Celery('tasks', broker='amqp://localhost')
    
    @ac.task(name='tasks.apidata')
    def apidata():
        
        api = '*apiurl*:' + str(stopid)
        saveinfo = 'static/stop' + str(stopid)+ '.json'
    
        r = requests.get(api)
        jsondata = json.loads(r.text)
    
        with open(saveinfo, 'w') as f:
            json.dump(jsondata, f)
    

    【讨论】:

      猜你喜欢
      • 2014-03-27
      • 1970-01-01
      • 2017-03-05
      • 2013-03-11
      • 2018-07-01
      • 2012-12-07
      • 1970-01-01
      • 2012-05-23
      • 2019-07-29
      相关资源
      最近更新 更多