Отображение изображений из статической папки в 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.