Python Flask - url_for{} not accessing static folder [duplicate] - python

This question already has an answer here:
Flask Python not loading main.css
(1 answer)
Closed 1 year ago.
Have a directory structure as follows:
Flask_project
-env
-src
--app2.py
-static
--css
---main.css
-templates
--base.html
--index.html
-app.py
If I load the page using app.py in the main folder, the main.css file is loaded fine using: python app.py. This works from the following file:
from flask import Flask, render_template, url_for # import
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
However, if I load app2.py using python3 src\app2.py which is in the \src folder as follows, and redirects the template_folder:
from flask import Flask, render_template, url_for # import
app = Flask(__name__, template_folder='../templates')
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
I am unable to load the css\main.css folder, I get the following error:
"GET /css/main.css HTTP/1.1" 404 -
I don't see why placing the app_whatever.py file in a sub directory (in this case \src) makes it unable to locate the main.css file?
For reference the base.html is as follows:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{url_for('static', filename='css/main.css') }}">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
And index.html is:
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% block body %}
<h1> Template </h1>
{% endblock %}

As mentioned in your second question, you need to define the location of your static-folder:
app = Flask(__name__, template_folder='../templates', static_folder='../static')

Related

render_template HTML renders but variables not evaluated

I am trying to build an "enterprise grade" version of a flask app so am using blueprints and a fancy directory structure. I have a "toy" version of this app where everything is in a very flat directory structure with no blueprints and it works.
I have a route program that calcs some variables then passes them to render_template to generate html. The html displays in the browser but all of the variables appear to be set to NONE.
My app uses blueprints and SQLite3.
I have tried multiple things to isolate the error.
Make a textual change to html template to ensure the right template is being picked up. It is.
Pass trivial string variable to html template and see if they show up, they don't.
View source of rendered html, there is nothing where the flask variable names {{ x }} occur in the html template, including the {{ x }} text itself. So it appears the value None has been been used.
Test the code leading up to the render_template, it works perfectly.
My directory structure is: -
\myapp
app.py
\app
__init__.py
\main
__init__.py
routes.py
...
\meta
__init__.py
routes.py
...
\templates
...
base.html
index.html
The code in \meta\routes.py (which corresponds to the meta blueprint) works down to and including entitys = stmt.fetchall() and is: -
from flask import Flask, render_template, request
import sqlite3 as sql
from app.meta import bp
from app import Config
config = Config()
metafile = os.path.join(config.META_DIR, config.META_MS, config.META_DB)
#bp.route('/', methods=['GET', 'POST'])
#bp.route('/index', methods=['GET', 'POST'])
def index():
meta = sql.connect(metafile)
stmt = meta.cursor()
stmt.execute("SELECT * FROM [meta.Entity]")
entitys = stmt.fetchall()
return render_template("index.html", entitys = entitys)
In case it is relevant here is \meta\__init__.py: -
from flask import Blueprint
bp = Blueprint('meta', __name__)
The template html is as follows. The base.html is: -
<!doctype html>
<html>
<head>
{% if title %}
<title>{{ title }} - Metapplica</title>
{% else %}
<title>Metapplica</title>
{% endif %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{ url_for('static', filename = 'w3.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename = 'style.css') }}">
</head>
<body>
<div>
Home
</div>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
and index.html is: -
{% extends "base.html" %}
{% block content %}
<h2>Entities</h2>
<table border = 1>
<thead>
<td>Entity</td>
<td>Action</td>
</thead>
{% for entity in entitys %}
<tr>
<td>{{ entity["Name"] }}</td>
<td>
List
Add
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Finally the rendered html is this: -
<!doctype html>
<html>
<head>
<title>Home - Metapplica</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/w3.css">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div>
Home
</div>
<hr>
<h2>Entities </h2>
<table border = 1>
<thead>
<td>Entity</td>
<td>Action</td>
</thead>
</table>
</body>
</html>
In response to #Tobin's comment I have included the code that (should) be registering the blueprint. I use an application factory.
Here is app\__init__()
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from flask import Flask, session, redirect, url_for, escape, request, current_app
from config import Config
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Register blueprints
from app.errors import bp as errors_bp
app.register_blueprint(errors_bp, url_prefix='/err')
from app.auth import bp as auth_bp
app.register_blueprint(auth_bp, url_prefix='/auth')
from app.meta import bp as meta_bp
app.register_blueprint(meta_bp, url_prefix='/meta')
from app.main import bp as main_bp
app.register_blueprint(main_bp)
return app
and here is the code that calls it: -
from app import create_app
app = create_app()
I suspect that somehow when Flask renders the html template the passed variables are not available to the "flask engine" which is pointing somewhere else.
Nothing fails and there are no error messages.
What am I doing wrong?

Flask template extending issue

Flask template extension doesn't work for some reason.
I've created a basic flask app with the following file structure:
__init__.py is empty
The code from app.py is:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template("index.html")
if (__name__ == "__main__"):
app.run()
The code from index.html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>from index</h1>
{% block ext %}
{% endblock %}
</body>
</html>
The code from ext.html is:
{% extends "index.html" %}
{% block ext %}
<h2>from ext</h2>
{% endblock %}
When I run in command line python app.py it gives no errors or warnings, logs are just
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [27/Sep/2017 14:48:40] "GET / HTTP/1.1" 200 -
But in the browser, the only output I have is "from index". So Flask doesn't see template extension from ext.html, and I don't see "from ext" in the browser. What's wrong here? Is there a typo somewhere?
You're rendering the wrong thing. Inheritance goes from child to parent; if you want the child template to be used, then that's what you need to call.
def index():
return render_template("ext.html")

Internal Server Error when trying to run flask

I am trying to create a website with a web form in it using flask, but I keep getting an Internal Server error, despite getting no error when I run it in the console
Here is my code:
__init.py
from flask import Flask, render_template
from forms import TestForm
app = Flask(__name__)
app.config.from_pyfile('config.py')
#app.route('/')
def homepage():
return render_template("main.html", form=TestForm())
if __name__ == "__main__":
app.run(debug=True)
forms.py
from flask_wtf import Form
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class TestForm(Form):
test_form = StringField('test_form', validators=[DataRequired()])
config.py
WTF_CSRF_ENABLED = True
SECRET_KEY = '<super-secret>'
main.html
<DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<meta name="viewport" content="width=device-width"
initial=scale=1/>
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='favicon.ico') }}" rel="shortcut icon">
</head>
<h2>Hello, this site is meant to test my fill_web_form.py script</h2>
<br>
<br>
<h1>Test Form</h1>
<form action="/" method="post" name="login">
{{ render_field(form.test_form(size=80) }}<br>
<p><input type="submit" value="Sign In"></p>
</form>
</html>
When I run flask run I get this
$ flask run
* Serving Flask app "FlaskApp"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
When I try to access http://127.0.0.1:5000/ in both chrome and firefox I get an error, but I feel like that's a whole separate question.
If all of your codes are here then I can tell you the problem might be about rendering form, try this one (pip install flask-bootstrap):
# __init.py
...
bootstrap = Bootstrap(app)
main.html
{% import 'bootstrap/wtf.html' as wtf %}
...
{{ wtf.quick_form(form) }}
...

404 error for CSS file in Flask Application

I am unable to find exact path of .css file in my flask app. Following is relevant code
layout.html
<!DOCTYPE html>
<html>
<head>
<title>An App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div id="container">
<div id="heading"><h3>App</h3></div>
{% block content %}{% endblock %}
</div>
</body>
</html>
+app
+static
style.css
+templates
__init__.py
forms.py
models.py
views.py
db_repository
.gitignore
app.db
config.py
db_create.py
The one with + sign are folders
Update:
I tried this in __init__.py, same result
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
app.config.from_object('config')
app._static_folder = os.path.abspath("static/style.css")
print os.path.abspath(app._static_folder)
db = SQLAlchemy(app)
from app import views, models
The link http://127.0.0.1:5000/static/style.css gives 404 error
Static should be on the same level as templates, not under app. Have you tried that?
I you want to change the route to the static asset's folder you could do:
app = Flask(__name__, static_folder='app/static')
check this here

flask isnt reading or interpreting css file

I'm basically trying to follow this tutorial ( http://net.tutsplus.com/tutorials/python-tutorials/an-introduction-to-pythons-flask-framework/)
Now when the css part comes in, and i copy the code it simply wont come out styled even afterr main.css is added it still shows up unstyled like if it wasn't importing the css file here's the HTML code
<!DOCTYPE html>
<html>
<head>
<title>Flask</title>
<strong><link rel="stylesheet" type"text/css" href="{{ url_for('static', filename='css/main.css') }}"></strong>
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Flask App</h1>
</div>
</header>
<div class="container">
{% block content %}
{% endblock %}
</div>
</body>
</html>
layout.html ^
Home.html v
{% extends "layout.html" %}
{% block content %}
<div class="jumbo">
<h2>Welcome to the Flask app<h2>
<h3>This is the home page for the Flask app<h3>
</div>
{% endblock %}
routes.py v
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
if __name__ == '__main__':
app.run(debug=True)
This is probably due to the directory structure of your app. By default, flask looks for the static directory in the same level as the file that the app object is created in. This is the example structure for a small application from the flask docs.
/yourapplication
/yourapplication.py
/static
/style.css
/templates
layout.html
index.html
login.html
You can also change the location of the static files by setting the "static_folder" attribute on the app object. Check the docs here for setting the static_folder

Categories