简体   繁体   中英

ImportError: No module named views

Im writing a web app in flask that displays bus stops pulled from an api.

i have a form on index.html where a user can input a stop number, that number gets picked up in views.py where the function also runs a task through celery to fetch the api data:

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')

here is my 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)

I am importing stopno from views into tasks so i can search the api for the specified stop, currently when a user inputs a stop number the action.html loads fine and displays the stop number the user inputs but no new file or data is created for the stop number and celery throws an error saying

ImportError: No module named views

structure of my project is

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

You are trying to do a relative import but you are not making it explicitly relative, which may or may not work, and which can cause unexpected errors. You should make your import explicitly relative with:

from .views import stopno

This way you don't have to worry about reproducing the entire path to the module.

from app.views import stopno

??

The import doesn't work for you because you are trying an implicit relative import .

This was supported in python 2 but not supported in python 3 .

Try this one : from .views import stopno , this is an explicit relative import which is supported in python 3

If that doesn't work

Try importing all from views like this : from .views import *

Always remember, in python 3 , import * is supported only on module level, not inside functions like this:

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

So if you are using : from .views import * , make sure you put it like this:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM