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