I am getting a template not found error while trying to run a flask app using blueprints. The template directory is located at the root directory as expected at the same level as the app directory. I am not very sure why this is happening.
The directory structure
root/
app/
blueprint1/
routes.py
__main__.py
templates/
base.html
index.html
routes.py
from flask import Blueprint, render_template
blueprint = Blueprint(
"blueprint", __name__, template_folder="templates")
#blueprint.route("/", methods=["GET", "POST"])
def index():
return render_template("index.html")
Error
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: index.html
main.py
from flask import Flask
from app.blueprint1.routes import blueprint
def create_app():
app = Flask(__name__)
app.register_blueprint(blueprint)
return app
def _main():
daemon_app = create_app()
daemon_app.run(debug=True)
if __name__ == "__main__":
_main()
This works, I edited it a little
routes.py
from flask import Blueprint, render_template
blueprint = Blueprint("blueprint", __name__, template_folder="../../templates")
#blueprint.route("/", methods=["GET", "POST"])
def index():
return render_template("index.html")
__main__.py
from flask import Flask
from routes import blueprint
def create_app():
app = Flask(__name__)
app.register_blueprint(blueprint)
return app
def _main():
daemon_app = create_app()
daemon_app.run(debug=True)
if __name__ == "__main__":
_main()`
Based on your file structure, your blueprint renders html files from the main template folder. It might work if you remove the template_folder argument from routes.py file.
I copied your codes and tried to emulate the error but it works for me. A year ago I have the same problem and somehow I solved it. Since I can't emulate the error I can't solve your problem.
Instead, I will just give you advise. You are making an effort to create blueprints in their own package, and yet you are using the main template folder. When you have a lot of blueprints managing the template folder will become a challenge. Thus, I recommend putting the html file within the blueprint package itself.
Here's the file structure:
root/
app/
blueprint1/
pages/blueprint1/index.html
routes.py
__main__.py
templates/
base.html
and routes.py should be like this
blueprint = Blueprint(
"blueprint", __name__, template_folder="pages")
#blueprint.route("/", methods=["GET", "POST"])
def index():
return render_template("blueprint1/index.html")
Related
This is the code read but Flask not rendering html
from flask import Flask,render_template
import psycopg2
import psycopg2.extras
app=Flask(__name__)
app.route('/')
def index():
return render_template('index.html')
if __name__=="__main__":
app.run(debug=True, port=9001)
If I'm not mistaking, it's just a typo error. Supposed you already have a file called index.html in your templates folder. So your tree look like this:
.
└── my_app/
├── templates/
│ └── index.html
└── run.py
This code should work:
from flask import Flask, render_template
app=Flask(__name__)
#app.route('/') # <-- You are missing the '#' here
def index():
return render_template('index.html')
if __name__ == "__main__": # <-- Note this too
app.run(debug=True, port=9001)
Now you can access to your project at http://127.0.0.1:9001/
To learn more about Flask view decorator, go here.
For more information about what mean if __name__ == "__main__":, you can read more here.
I structured my app like the following using blueprints. The view files are
extremely huge so I divided them into multiple files.
myapp/
__init__.py
admin/
__init__.py
views1.py
views2.py
views3.py
views4.py
static/
templates/
models/
models.py
myapp/init.py
from flask import Flask
from myapp.admin import admin_bp
app = Flask(__name__)
app.register_blueprint(admin_bp)
myapp/admin/__init__.py
from flask import Blueprint, g
from flask_login import current_user
admin_bp = Blueprint('admin', __name__, template_folder='templates')
#admin_bp.before_request
def load_logged_in_user():
if current_user and not current_user.is_anonymous:
user_name = current_user.user_name
g.user = Account.get(user_name)
from . import views1, views2, views3, views4
myapp/admin/view1.py
from . import admin_bp
#admin_bp.route('/hello', methods=['GET'])
def hello():
return 'Hello'
This is working without any specific errors. But those view files and admin/__init__.py file are importing each other (circular dependency), which should be avoided. How to structure my app using blueprints without circular dependency?
I think it is better to use separate blueprints for each view.
Otherwise to avoid circular dependencies you can use add_url_rule() method. So you will have the following files:
myapp/admin/__init__.py
from flask import Blueprint, g, session, abort, request
from flask_login import current_user
admin_bp = Blueprint('admin', __name__, template_folder='templates')
#admin_bp.before_request
def load_logged_in_user():
if current_user and not current_user.is_anonymous:
user_name = current_user.user_name
g.user = Account.get(user_name)
from . import views1, views2
bp.add_url_rule('/hello', view_func=views1.hello)
bp.add_url_rule('/hello2', view_func=views2.hello2)
myapp/admin/view1.py
def hello():
return 'Hello'
from flask import Flask,render_template
app = Flask(__name__, template_folder='home/root13/webapp.html/staic/')
#app.route("/index.html")
def hello():
return render_template('index.html')
#app.route("/home")
def hello_world():
return render_template('post.html')
if __name__ == "__main__":
app.run(debug=True)
Flask will try to find the HTML file in the templates folder, in the same folder in which this script is present.
-Application folder
-Hello.py
-templates
-hello.html
You should put all HTML files inside a folder named templates
I am trying to organize my flask project, but there's something wrong.
I have this directory:
app/
__init__.py
views/
pages.py
On my __init__.py file I've imported the pages object and
registered it as a blue print.
This is the code on my pages.py file.
from flask import Blueprint, render_template
pages = Blueprint('pages', __name__) #no prefix
#pages.route('/')
def index():
return '<h1>in index.html</h1>'
#pages.route('/home')
def home():
return '<h1>in home.html</h1>'
If I run the flask app, open the browser, and go to localhost:5000,
I will see the headline 'in index.html'.
But if I go to localhost:5000/home, I will get the message 404 Not Found message.
Does anyone know the reason for this behavior?
Ok, first the folder structure:
app/
__init__.py
main.py
views/
__init__.py
test.py
Contents of main.py:
from flask import Flask
from views.test import pages
app = Flask(__name__)
app.register_blueprint(pages) <-- blueprint registration
Contents of test.py:
from flask import Blueprint
pages = Blueprint('pages', __name__) #no prefix
#pages.route('/')
def index():
return '<h1>in index.html</h1>'
#pages.route('/home')
def home():
return '<h1>in home.html</h1>'
I believe the register_blueprint was the only thing missing.
When stuff like that happen, just turn off everything, reset your computer.
Sometimes the bug is not yours.
I have the following structure in my project
\ myapp
\ app
__init__.py
views.py
run.py
And the following code:
run.py
from app import create_app
if __name__ == '__main__':
app = create_app()
app.run(debug=True, host='0.0.0.0', port=5001)
views.py
#app.route("/")
def index():
return "Hello World!"
_init_.py
from flask import Flask
def create_app():
app = Flask(__name__)
from app import views
return app
I'm trying to use the factory design pattern to create my app objects with different config files each time, and with a subdomain dispatcher be able to create and route different objects depending on the subdomain on the user request.
I'm following the Flask documentation where they talk about, all of this:
Application Context
Applitation Factories
Application with Blueprints
Application Dispatching
But I couldn't make it work, it seems that with my actual project structure there are no way to pass throw the app object to my views.py and it throw and NameError
NameError: name 'app' is not defined
After do what Miguel suggest (use the Blueprint) everything works, that's the final code, working:
_init.py_
...
def create_app(cfg=None):
app = Flask(__name__)
from api.views import api
app.register_blueprint(api)
return app
views.py
from flask import current_app, Blueprint, jsonify
api = Blueprint('api', __name__)
#api.route("/")
def index():
# We can use "current_app" to have access to our "app" object
return "Hello World!"