Sorry I've searched inside the stackoverflow and googled, but no useful information found.
I have an flask application,
python version 2.6
flask version 0.9
its application hierarchy is like
application/
__init__.py
app.py
hello/
__init__.py
view.py
templates/
hello.html
both files init.py are empty
app.py
-----------------------
from flask import Flask
from flup.server.fcgi import WSGIServer
from hello.view import hello
app = Flask(__name__)
app.debug = True
app.register_blueprint(hello, url_prefix='/hello')
if __name__ == '__main__':
WSGIServer(app, bindAddress='/tmp/app.sock').run()
view.py
-----------------------
import os
from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound
hello = Blueprint('hello', __name__, template_folder='templates')
#hello.route('/')
def get_index():
try:
return render_template('hello.html')
except TemplateNotFound:
abort(404)
hello.html
-----------------------
<!DOCTYPE html>
<html>
<head>
{% block head %}
<meta charset="utf-8">
{% endblock %}
</head>
<body>
<div>
{% block body %}
<h1>Click Me</h1>
{% endblock %}
</div>
</body>
</html>
It works fine when I enter localhost:8080/hello, but turns out error if I click the link in html. I found its url value is href="/hello/hello/" (Should it be /hello/ right?).
I know hello.get_index is mapped to /hello/, but have no idea that the first one hello/ comes from. Any hint is appreciated.
Have you tried removing the url_prefix parameter when you regisger the blueprint? For example, what if you change the following from :
app.register_blueprint(hello, url_prefix='/hello')
to
app.register_blueprint(hello)
Related
I have a form on one page that I want to submit to another page. I can't figure out how to create the link to that second page.
Project layout:
Fileserver/
config.py
requirements.txt
run.py
setup.py
app/
__init__.py
static/
css/
img/
js/
templates/
formAction.html
formSubmit.html
index.html
__init__.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
ip = request.remote_addr
return render_template('index.html', user_ip=ip)
index.html:
<!DOCTYPE html>
<html lang="en">
<body>
<ul>
<li>Check Out This Form!
</ul>
</body>
</html>
I can see the page at localhost:5000/ without issue.
I have also tried:
as well as:
What am I missing?
url_for generates urls to routes defined in your application. There are no (or should probably not be any) raw html files being served, especially out of the templates folder. Each template should be something rendered by Jinja. Each location you want to display or post a form to should be handled and generated by a route on your application.
In this case, you probably want to have one route to both render the form on GET and handle the form submit on POST.
__init__.py:
from flask import Flask, request, url_for, redirect, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/cool_form', methods=['GET', 'POST'])
def cool_form():
if request.method == 'POST':
# do stuff when the form is submitted
# redirect to end the POST handling
# the redirect can be to the same route or somewhere else
return redirect(url_for('index'))
# show the form, it wasn't submitted
return render_template('cool_form.html')
templates/index.html:
<!doctype html>
<html>
<body>
<p>Check out this cool form!</p>
</body>
</html>
templates/cool_form.html:
<!doctype html>
<html>
<body>
<form method="post">
<button type="submit">Do it!</button>
</form>
</html>
I don't know what your forms and routes actually do, so this is just an example.
If you need to link static files, put them in the static folder, then use:
url_for('static', filename='a_picture.png')
So what I just found was that if I don't wrap the href in parenthesis it works and I also created a link to return back a page
#app.route('/blog')
def blog():
return '<h1>These are my thoughts on <a href=blog/2020/dogs>dogs</a></h1>'
#app.route('/blog/2020/dogs')
def blog2():
return '<h3>these are my dogs <a href=../../blog>home</a></h3>'
The following code works perfectly from the .py file but I want to separate the HTML and put it in templates/index.html.
I suppose I have to use the render_template function in Flask to be able to return the same results.
# File dynamic_website.py
from owlready2 import *
onto = get_ontology("bacteria.owl").load()
from flask import Flask, url_for
app = Flask(__name__)
#app.route('/')
def ontology_page():
html = """<html><body>"""
html += """<h2>'%s' ontology</h2>""" % onto.base_iri
html += """<h3>Root classes</h3>"""
for Class in Thing.subclasses():
html += """<p>%s</p>""" % (url_for("class_page", iri = Class.iri), Class.name)
html += """</body></html>"""
return html
I created a folder template and a file index.html. I used return render_template('index.html') but it doesn't work. What arguments do I have to add to the return_template function? "for Class in Thing.subclasses():" have to be in the .html file or .py file? What about the url_for function?
If you could edit the .py code and let me know what should I write exactly in the index.html file to have the same results it would be great.
UPDATE:
What I have done:
Python code
from flask import Flask, render_template
from owlready2 import *
from flask import Flask, url_for
onto = get_ontology("bacteria.owl").load()
app = Flask(__name__)
#app.route("/")
def ontology_page():
for Class in Thing.subclasses():
return render_template('index.html')
Html code
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>{{ Class.name }}</h1>
</body>
</html>
You can't return a function multiple times. Whatever is returned, is the value of the function. This tutorial is in JS, but it implies the same concept as python does.
If you want the user to see a list of things on the html, do this. render_template('index.html', things=Thing.Subclasses()) This will give Jinja a list, where it can then for loop.
For html you can do this
{% for s in things %} {{ s }} is something {% endfor %}. Do anything you want with the s though, s is one subclass from the list.
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')
When I try to use a varible from a url argument the text disappears, here's the app.py code:
from flask import Flask, render_template
import os
TEMPLATE_DIR = os.path.abspath('templates')
STATIC_DIR = os.path.abspath('static')
app = Flask(__name__, template_folder=TEMPLATE_DIR, static_folder=STATIC_DIR)
#app.route('/<string:name>')
def home(name):
return render_template('index.html', variable=name)
Here's what I am doing in the index.html file in templates folder:
<body>
<h1 class="header">Hello {{ name }}</h1>
<h3>Attention! This is a testing website with learning purpouses.</h3>
</body>
But when I run the app.py no error is displayed but it doesnt display the Hello {{ name }} line
Try this since you have assigned your name value to variable in your code :
<body>
<h1 class="header">Hello {{ variable }}</h1>
<h3>Attention! This is a testing website with learning purpouses.</h3>
</body>
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