12

flaskr.py

# flaskr.py    
from flask import Flask


app = Flask(__name__)

import views


if __name__ == "__main__":
    app.run()

views.py

# views.py
from flaskr import app
from flask import render_template, g

@app.route('/')
def show_entries():
    entries = None
    return render_template('show_entries.html', entries=entries)

python3 flaskr.py

Can anyone tell me why this isn't working but if i move the whole app into a separate package it works flawless.

No errors, not nothing except a 404 like the views.py is ignored. I'm knew to Flask and i'm trying out different things to understand how it actually works.

Thanks!

Viorel
  • 1,420
  • 1
  • 17
  • 27

4 Answers4

13

If you want to move views to other file you need to register blueprint:

flask.py

# flaskr.py    
from flask import Flask
from .views import my_view

app = Flask(__name__)
app.register_blueprint(my_view)

if __name__ == "__main__":
    app.run()

views.py

# views.py
from flaskr import app
from flask import render_template, g

my_view = Blueprint('my_view', __name__)

@app.route('/')
def show_entries():
    entries = None
    return render_template('show_entries.html', entries=entries)

Similar questions:

Community
  • 1
  • 1
KiraLT
  • 2,385
  • 1
  • 24
  • 36
  • 1
    I like vergzeug's url mapping with endpoints and don't understand idea of Blueprints. do U know good tutorials for it? – akaRem Dec 01 '13 at 12:41
  • Thanks @Lukas but that's not what i was looking for. Just wanted to figure out why it's not working like above. – Viorel Dec 02 '13 at 04:40
  • 7
    There is a cycle import in your example, isn't there? – smirnoffs Jul 25 '15 at 11:19
  • 1
    ImportError: cannot import name 'my_view' from partially initialized module 'views' (most likely due to a circular import) –  Aug 28 '21 at 12:18
3

Apparently, this has to do with app.root_path.

  • In views.py, app.root_path is /path/to/project/flaskr
  • But in flaskr.py, app.root_path is /path/to/project

So Flask expects views.py to be put into a package.

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Viorel
  • 1,420
  • 1
  • 17
  • 27
  • Can someone elaborate a bit more on this answer? It sounds like the importing in at least one of the files only works correctly when it is in a package. But how can that be? The relative position of the files is the same in either case so why would the path change? – Luke Feb 08 '20 at 11:25
1

I solved this issue for me by adding a wilcard in flaskr.py. I saw this idea first at https://github.com/jennielees/flask-sqlalchemy-example, however I am now trying to do a blueprint as it is better to maintain the code in the long run I believe.

flaskr.py

# flaskr.py    
from flask import Flask

app = Flask(__name__)

# import views
from views import *

if __name__ == "__main__":
    app.run()

views.py

# views.py
from flaskr import app
from flask import render_template, g

@app.route('/')
def show_entries():
    entries = None
    return render_template('show_entries.html', entries=entries)
0

In version 1.1.x, there is the add_url_rule() method where the views are loaded lazily from a separate module by placing view functions undecorated in a separate module, say views.py, and in the app file, one calls it as views.app.add_url_rule(path, view_func=views.view_func) in the same way as when we placed the route decorators above their view functions in the same file.

I'd also like to add this post as a resource