Reputation: 9
Im new to web development and especially Flask and python. I´m trying to create site where you can browse images and once you click on one, that image will be shown on another page called image.html. My issue is that i dont know how to pass the img src and then fetch it on the server side, and pass it back to the rendered template.
(The images are stored under /static folder) app.py:
from flask import Flask, render_template, request, Response, redirect
import os
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/image/<id>', methods=['GET', 'POST'])
def image(id):
#fetch image based on id?
return render_template('image.html', id=id)
if __name__=='__main__':
app.run(debug=True)
index.html:
{% extends 'base.html' %}
{% block content %}
<a href="/image/123">
<img src="static/123.jpg" id="123" alt="" width="400" height="400">
</a>
{% endblock %}
image.html:
{% extends 'base.html' %}
{% block content %}
<img src="{{ url_for('static',filename='{{ id }}') }}" id="123" alt="" width="400" height="400">
{% endblock %}
Upvotes: 0
Views: 1279
Reputation: 8592
It is quite possible to achieve your stated goal with Flask alone and you are already on a possible path to the solution.
The following routes are based on your code. In addition, all files within the static directory are listed in index
and transferred to the template.
from flask import Flask, render_template
import os
app = Flask(__name__)
@app.route('/')
def index():
# Alternatively use app.static_folder here!
files = os.listdir(os.path.join(app.root_path, 'static'))
return render_template('index.html', files=files)
@app.route('/image/<path:id>')
def image(id):
return render_template('image.html', id=id)
In the template itself, you can then iterate over the list of file names and use url_for
to refer to the second route and transfer the file name as a variable of the route, as well as to the file itself within the img element. See also "Variable Rules" and "Static Files".
Within the anchors it is possible to simply enter the same information to refer to the picture. However, if you want to embed the image on another page as described, I recommend that you pass the full file name as the path.
{% extends 'base.html' %}
{% block content %}
{% for file in files %}
<a href="{{ url_for('image', id=file) }}">
<img src="{{ url_for('static', filename=file) }}" alt="{{ file }}" width="400" height="400" />
</a>
{% endfor %}
{% endblock %}
Since you are already within an expression for a code block for the url_for
specification, you do not need any further curly brackets and you can simply pass the variable passed to the template as a filename.
{% extends 'base.html' %}
{% block content %}
<img src="{{ url_for('static', filename=id) }}" width="400" height="400">
{% endblock %}
I would advise you to put all the images in a sub-folder so that it is easier to separate them from other files. The procedure remains the same, only the path details vary.
Since I think that you are also interested in uploading new images to the server, I recommend this and this tutorial. On the last mentioned page you will find what I think is an excellent introduction to the framework and helpful articles on various topics related to flask.
Upvotes: 1
Reputation: 368
If I understood your problem you can solve put a simple link in your index template to your image function ...
<a href="{{url_for('.image', id=123)}}">
<img src="static/123.jpg" id="123" alt="" width="400" height="400">
</a>
Upvotes: 0