I am very new to python and Flask.
I have a folder with a list of jpeg images. I have to display them in my demo application with flask as below,
My app.py :
#app.route("/")
def home():
return render_template('home.html')
My home.html:
<img id="person" src={{ url_for('static',filename='pferson_folder/000_1.jpg') }}>
In the above code, I don't want to hardcode the images in the HTML tag. it needs to take the image source from folder dynamically.
Would you please help me with this. Thank you.
You can read all the file names out of the directory using os.listdir('Your path') and pass the array into the template:
Something like:
# Inside app.py
import os
#app.route('/')
def home():
image_names = os.listdir('Your path to images folder')
render_template('home.html', image_name=image_names)
And inside your template:
{% for name in image_names %}
<img src="{{ url_for('static', filename='pferson_folder/' + name) }}" >
{% endfor %}
Then you don't have to hardcode the names.
Related
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 trying to make a loop to show images in a slideshow in flask, but I want to take the images that put the name of the image, I am trying with glob but this gives the following error:TypeError: 'module' object is not callable
python code
from flask import Flask, render_template
import glob
import os.path
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def home():
ruta_imagenes = glob(os.path.join(app.static_folder, "img"))
render_template('index.html',ruta_imagenes=ruta_imagenes )
if __name__ == ('__main__'):
app.run(debug=True)
HTML
<div class="carousel-inner">
{% for _, ruta in enumerate(rutas_imagenes) %}
<div class="carousel-item ">
{% if _ == 0 %}active{% endif %}
<img src="{{ ruta }}" class="d-block w-100" alt="...">
</div>
{% endfor %}
</div>
You're importing glob and then just calling it. But glob is a module.
What you want is either
import glob
glob.glob(os.path.join(app.static_folder, "img"))
or
from glob import glob
glob(os.path.join(app.static_folder, "img"))
As #blueteeth mentioned you are importing glob module, which is not callable. You probably meant glob.glob() - a function, inside the glob module.
However, even then, glob is probably not what you are looking for. If you want to get a list of images you need to read files in the directory with something like:
ruta_imagenes = []
for root, dir, file in os.walk(path):
ruta_imagenes.append(file)
And, of course, don't forget to pass these images to your template
I'm setting an application where I need to display some image. My images are located outside of my app's folder, that's why I've used this:
#app.route('/<path:filename>')
def download_file(filename):
return send_from_directory(MEDIA_FOLDER, filename=filename, as_attachment=True)
The architecture of my folders is:
--images1
|__ image1.png
|__ image2.png
--images2
|__ image3.png
|__ image4.png
--web
|__ app.py
|__ templates
|__ index.html
I've stored all my images path in a list as:
images_path = ['image1.png', 'image2.png', ...]
At the moment, I've tried to display the images as:
{% for image in images_path %}
<img src="{{ url_for('download_file', filename="{{ image }}") }}">
Using this, it displays always the same image. In my example the image1.png.
I've tried to check if the for loop works, and it works.
I've tried this:
{{ image }} CHECKER
<img src="{{ url_for('download_file', filename="{{ image }}") }}">
and it displays on my page:
>>>
image1.png CHECKER then the `image1.png`
image2.png CHECKER but also `image1.png`
UPDATE 1
In my app.py, I've added this:
#app.route('/<path:filename>')
def download_file(filename):
images_folder = [images1, images2]
try:
for image_folder in imagesfolder:
MEDIA_FOLDER = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + str(image_folder) + "\\"
return send_from_directory(MEDIA_FOLDER, filename=filename, as_attachment=True)
except FileNotFoundError:
abort(404)
and on my template.html, I've added this:
{% for image in images_path %}
<img src="{{ url_for('download_file', filename=image) }}">
How can I correctly set the path here?
How can I link the images and its directory?
UPDATE 2
I've changed my script by:
#app.route('/<path:filename>')
def download_file(filename):
try:
return send_file(filename, as_attachment=True)
except FileNotFoundError:
abort(404)
The filename will be defined by:
>>>> filename = str(os.getcwd()) + str(list_machine[i]) + str(elem)
When I inspect the elements on my page, the URL seems to be right but the image is not displayed.
How can I display all the images stored in my folders?
Thanks in advance.
You could try this:
<img src="{{ url_for('download_file', filename=image) }}">
with the image variable defined as: image = str(os.getcwd()) + '/path/to/image'
You must define this variable by listing your files, you can use: os.listdir('path/directory').
Your function named download_file should be:
#app.route('/<path:filename>')
def download_file(filename):
try:
filename=os.path.join(app.root_path, filename)
return send_file(filename)
except FileNotFoundError:
abort(404)
Don't forget to import the send_file function.
It works for me. Hope it helps.
The problem doesn't come from {{ image }} but I don't see in your code {% endfor %} after the html img.
So the correct code is :
{% for image in images_path %}
<img src="{{ url_for('download_file', filename="{{ image }}") }}">
{% endfor %}
UPDATE 1:
I think you make several mistakes in your code :
#app.route('/<path:filename>')
def download_file(filename):
images_folder = ['images1', 'images2']
MEDIA_FOLDER = []
try:
for image_folder in imagesfolder:
MEDIA_FOLDER.append(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + str(image_folder) + "\\")
return send_from_directory(MEDIA_FOLDER, filename=filename, as_attachment=True)
except FileNotFoundError:
abort(404)
I wasted a lot of time to find out what is wrong. I need your help now.
I want to render template with image from my filesystem. But it is not working.
Path - string that contains file name
#app.route('/', methods=['GET'])
def main():
return render_template('main.html',image = path)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<h2></h2>
<form method="post" enctype="multipart/form-data" action="/uploader">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
<img src={{ url_for('static', filename = image) }} >//i can't figure how to change this to use {{image}}
</body>
</html>
Just generate full image path in your view and pass it to your template
#app.route('/', methods=['GET'])
def main():
#path is filename string
image_file = url_for('static', filename=path)
return render_template('main.html', image_file=image_file)
and then just use it as full link
<img src={{ image_file}} >
if you have image file (with filename which stored in path) in your static folder this should work
If you was set the static folder like that (or other methods):
from flask import Flask
app = Flask(__name__, static_folder='static')
#app.route('/', methods=['GET'])
def main():
return render_template('main.html', image = url_for("static", filename=path))
or shorter:
return render_template('main.html', image='/static/' + path))
after you will put your image in /static folder you can get it from template:
<img src="{{image)}}">
I think something like this should work.
<img src="{{ url_for('static', filename='image') }}">
Where 'image' refers to the path of the image file inside static folder. Make sure to use the full name of image file along with its file type i.e. jpg, png etc.
I am new to Django.I have the following code on my html file:
{% load staticfiles %}
<form method="post"> {% csrf_token %}
<input type="file" name="file">
<button>Submit</button>
</form>
{{file}}
<img class="hl" src="{{ MEDIA_URL }}photos/abc.png" /></a>
<img class="hl" src="{% static 'blog/images/sec.png' %}" /></a>
and my views.py for the above code is:
if request.method == 'POST':
if 'file' in request.POST:
f = request.POST['file']
a = MyUser(email="frt#wer.com", date_of_birth=date.today())
a.photo.save('somename.png', File(open(f, 'r')))
a.save()
context = {'file': f}
return render(request, 'home.html', context)
Now browsers do not return the absolute path of the file from user's local device, it just gathers filename because ofsome security issues but a.photo.save('somename.png', File(open(f, 'r'))) this part of my code needs absolute path of user local device that is something like /home/abc/Pictures/sec.png all i get is sec.png and hence i am unable to upload.
From python manage.py shell:
>>>a = MyUser(email="frt#wer.com", date_of_birth=date.today())
>>>a.photo.save('somename.png', File(open('/home/abc/Pictures/sec.png', 'r')))
>>>a.save()
This works fine. Is there some workaround. I dont want to use Form.
I would suggest that if you want to allow for a file upload that you use a File form rather than a workaround. A simple and very succinct example can be found here:
Need a minimal Django file upload example