Динамический URL во flask не показывает фото с сервера

Делаю сайт-фотохостинг. Столкнулся с проблемой показа нужных изображений. Из динамического url адреса получаем переменные с именем файла и папки, в которой он лежит.

from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
    
app = Flask(__name__)
    
    
@app.route('/din/<folder_name>/<file_name>')
def test_din(folder_name, file_name):
    file = f'static\\{folder_name}\\{file_name}'
    return render_template('image_render.html', img=file)

image_render.html выглядит так

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" />
    <title>...</title>
</head>
<body>
{% if img %}
    <img src="{{img}}">
{% else %}
    <h1>Image will be render here...</h1>
{% endif %}
</body>
</html>

Файлы на сервере расположены в папке static, на скрине видна попытка перехода по url http://127.0.0.1:8001/din/est/a.jpg

введите сюда описание изображения

Я не могу понять, почему render_template не выдает нужный html с картинкой?

Если мы в функции-декораторе просто пропишем нужный URL и в render_template отправляем не динамические переменные, то все работает корректно. Например так

@app.route('/test')  #  это работает без динамических переменных
def mi():
    file = r'static\est\a.JPG'
    print(file)
    return render_template('image_render.html', img=file)

В данном случае любая картинка показывается по любому пути в папке static.

Причем если URL сделать динамическим, но в самом шаблоне декоратора прописать жесткий адрес, то картинка тоже не будет работать.

Проблема именно в работе render_template и динамического url. Хотя я сравнивал полученный в обоих случаях адрес командой print() и пути оказывались идентичными.


Ответы (1 шт):

Автор решения: CrazyElf

Из-за того, что путь к файлу в скрипте прописан относительный 'static/..., а не абсолютный, при обращении к URL, указывающему не на корень сайта, а куда-то глубже /din/est/..., общий путь формируется вида /din/est/static/..., что, конечно, неправильно.

В данном случае нужно указывать абсолютный путь от корня сайта /static, тогда полный путь будет правильно формироваться именно от корня сайта, а не от того пути, где лежит страница, к которой идёт обращение.

Ну и поскольку речь идёт об URL-ях, то экранированные обратные слеши \\ (как в файловой системе Windows) тут не нужны, используйте везде обычные слеши /, как принято в URL (и в Linux).

→ Ссылка