Отображение изображений из статической папки в Django

У нас есть проблема с отображением изображений на html-страницах. Мы создаем граф, сохраняем его и затем передаем его url на html-страницу через контекст, но django не может найти картинку (Error 404 Not Found). Нет никакой модели для хранения урлов, так как нет необходимости обращаться к ним позже.

Вот наш views.py:

def simple_upload(request):
    if request.method == 'POST' and request.FILES['file']:
        myfile = request.FILES['file']
        fs = FileSystemStorage()
        filename = fs.save(myfile.name, myfile)
        
        # this is the function that returns image url
        forecast, clean_df, graph_url = data_processing(myfile, filename)

        forecast = forecast.reset_index()
        cols_fc = forecast.columns.tolist()
        forecast[cols_fc[0]] = forecast[cols_fc[0]].dt.date
        forecast = forecast.values.tolist()

        clean_df = clean_df.reset_index()
        cols_df = clean_df.columns.tolist()
        clean_df[cols_df[0]] = clean_df[cols_df[0]].dt.date
        clean_df = clean_df.values.tolist()

        context = {
            'filename': filename,
            'cols_fc': cols_fc,
            'forecast': forecast,
            'cols_df': cols_df,
            'clean_df': clean_df,
            'graph_url': graph_url,
        }
        return render(request, 'project/results.html', context)
    return render(request,'project/example.html')

Функция data_processing():

def data_processing(filename):
    df = pd.read_excel(filename)
    cols = df.columns.values.tolist()
    df = df.set_index(cols[0])
    df = df[[cols[1]]]
    
    clean_df = process_missing(df)
    integr = stationate_data(clean_df)
    
    model_param = search_optimal_arima(clean_df, integr)
    model = sm.tsa.arima.ARIMA(clean_df, order=model_param, freq='MS')
    results = model.fit()
    
    forecast = get_forecast(results, clean_df, cols[1])
    graph_url = make_graph(forecast, clean_df, cols, filename)
    return forecast, clean_df, graph_url

Функция make_graph():

def make_graph(forecast, df, cols, filename):
    plt.figure(figsize=(16,4))
    plt.plot(df, label="Реальные значения", color="blue")
    plt.plot(forecast, label='Прогноз', color='red')

    plt.title(filename)
    plt.xlabel(cols[1])
    plt.ylabel(cols[0])
    plt.legend()

    figname = (f'{filename}_forecast.png')

    plt.savefig(os.path.join(settings.MEDIA_ROOT, 'graphs/', figname))

    return figname

Html-документ result.html:

<body>
{% load static %}
    <p>{{ filename }}</p>
    <p>------------------------------------------------------</p>
    <div>{{ graph_url }}</div>
    <img src="{% static '{{ graph_url }}' %}">
    <p style="color:red"> ------------ VALUES -----------</p>
    <p>{{ cols_df }}</p>
    {% for c in clean_df %}
        <p>{{ c.0 }} || {{ c.1 }}</p>
    {% endfor %}
    <p style="color:blue">------------- FORECAST -------------</p>
    <p>{{ cols_fc }}</p>
    {% for f in forecast %}
        <p>{{ f.0 }} || {{ f.1 }}</p>
    {% endfor %}
</body>

Статические/медийные урлы:

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, STATIC_URL)

MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(STATIC_ROOT, MEDIA_URL)

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'project/static/static_files/'),
    os.path.join(BASE_DIR, 'static/media/graphs/')
)

Мы пробовали передавать картинку разными способами:

  • Записываю полный url path/to/{{ url }} и со статической директорией {% static '{{ url }}'%}, но они не работают.

Мы уверены, что проблема кроется в graph_url, потому что когда мы передаем имя изображения из той же папки вручную (набирая его название как 'image.png'), оно отображается нормально. Есть идеи, почему так происходит?

Тег static возвращает только изображения/файлы из папки static, файлы, которые вы разместили вручную. Похоже, вы сохраняете их в папке media и вызываете тег static для рендеринга изображения, в результате чего django не может его найти. Может быть, сохранить файл в модели для рендеринга изображений

?

Встроенный шаблонный тег static принимает путь и urljoins со статическим префиксом STATIC_URL.


Когда у вас есть такое окружение:

ROOT URL: http://localhost:8000
STATIC URL: cdn/files

Тег img с тегом src:

{% static 'images/hi.jpg' %}

Его src нормализуется следующим образом:

http://localhost:8000/cdn/files/images/hi.jpg

И если файл hi.jpg существует в папке STATIC_ROOT/images, [1] этот файл будет получен браузером и отображен для вас.


If you don’t want this normalization, then don’t use the static tag. [2]

<img src="{{ graph_url }}">

[1] This folder doesn’t have to exist on the filesystem. See STORAGES. [django-docs]

[2] Only do this if you know what you are doing.

Вернуться на верх