I have a problem with the display of an image using the static
tag.
I have a class called ProfileView
that takes action when I log in on my login form. This class examines the profile data of the user who is about to log in and displays it on his home page, data such as name, username, photo, among others.
class ProfileView(LoginRequiredMixin, TemplateView):
template_name = 'profile.html'
def get_context_data(self, **kwargs):
self.request.session['Hi'] = True
context = super(ProfileView, self).get_context_data(**kwargs)
is_auth = False
name = None
#Pregunto si en el request va el user
user = self.request.user
#Indago sobre los posibles casos, falta hacer cuando un user sea paciente y medico
if user.is_medical:
#if self.request.user.is_authenticated():
print (user.is_medical)
is_auth = True
profile=user.get_medical_profile()
#name = self.request.user.username
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile, 'data':data})
elif user.is_patient:
print (user.is_patient)
is_auth=True
profile=user.get_patient_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
elif user.is_physiotherapist:
print (user.is_physiotherapist)
is_auth=True
profile=user.get_physiotherapist_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
return context
def get_userprofile(self):
return self.request.user.userprofile
My settings configuration is as follows:
I have a settings called base.py where in relation to the static files I have the following ( the DEBUG directive is not in this settings/base.py ):
Generally here I say that my static files are going to be centralized in a directory called static
thanks to the directive ofSTATIC_URL='/static/'
And then with STATICFILES_DIRS
I'm saying look for the static files within a directory named static
either in each application or in the main application created by Django when creating the project.
# settings/base.py
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'
# With this configuration, Django will look for static files in a folder named static inside each app and into the neurorehabilitation/static folder created.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
And I have a settings called development.py that inherits from base.py and has this configuration: Notice that I have the DEBUG=TRUE
in this settings/development.py
I've read that it DEBUG
should be on False
when you want to cache static files, although I don't know if it's also on when you want to serve them from the development environment.
Also in this settings/development.py
I have a directive called MEDIA_ROOT
through which I tell Django that when I upload a file, it is saved in a directory called "media".
And the directive MEDIA_URL
indicates that the files (images, sound, video) are going to be served from that url/media/
# settings/development.py
from .base import *
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': get_env_variable('DATABASE_NAME'),
'USER': get_env_variable('DATABASE_USER'),
'PASSWORD': get_env_variable('DATABASE_PASSWORD'),
'HOST': 'localhost',
'PORT': '5433',
}
}
MEDIA_URL = '/media/'
#Cuando suba los archivos de media (imagenes sonido, video), van a servirse
#desde ese url.
MEDIA_ROOT = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-2] + ['media'])
#Ahí le estamos diciendo que donde este, en la carpeta media, cree los
#elementos. Esto creara una carpeta media en el proyecto cuando subamos
#un archivo+
In my template profile.html
I am calling the image by invoking the photo attribute, which is a type field ImageField
which goes to the template thanks to the fact that in the previously shown view it was sent in the context.
It is inside the tag figure
that I intend to call the image like this:
{% load static from staticfiles %}
Here all the content of my templateprofile.html
{% extends 'base.html' %}
<!-- {% load staticfiles %} -->
{% block content %}
<div>
{% if userprofile %}
{{ userprofile.user.username }}, <a href="{% url 'logout' %}">Logout</a>
{% else %}
<a href="">Login</a>
{% endif %}
</div>
<div style=" ">
<figure style=" ">
{% load static from staticfiles %}
<img src="{% static '/media/{{ userprofile.user.photo }}' %}" alt="{{ userprofile.user.username }}">
<!-- <img src="/media/{{ userprofile.user.photo }}" alt="{{ userprofile.user.username }}"> -->
<figcaption>{{ userprofile.user.first_name }}</figcaption>
<!-- User esta relacionado 1 a 1 con userprofile model, por transitividad se llega
al campo username del modelo user desde userprofile-->
</figure>
</div>
{% endblock content %}
And this is how I get in my browser that the image does not appear, but the information related to the name and username of the user who just logs in
In my Django server log I get this:
[28/Dec/2015 08:14:58] "GET /accounts/profile/ HTTP/1.1" 200 5467
Not Found: /media/{{ userprofile.user.photo }}
[28/Dec/2015 08:14:58] "GET /media/%7B%7B%20userprofile.user.photo%20%7D%7D HTTP/1.1" 404 1885
When I call the image without using the tag static
but in the traditional way, that is to say in this way:
<img src="/media/{{ userprofile.user.photo }}" alt="{{ userprofile.user.username }}">
There the image that I want to call appears.
What configuration may I be missing? Or what can I be ignoring or overlooking?
Anyway something I plan to do in a short time is to centralize my files with collectstatic
and put them on a CDN like Amazon S3 or from NGINX on a server. But for the moment in development I would like to work with them like this.
I don't know what could be missing.
When you want to show files uploaded by users you have to use the
url
file attribute, something like this:Don't confuse them
static
with themedia
, the first one is for your JavaScript files, CSS, etc.; the second is for files uploaded by users. That said, you don't need to use{% load static from staticfiles %}
.If you have correctly defined the path where the files are uploaded, it doesn't make sense to use
/media/
in the path, even if this is correct, you are going against DRY since this is already defined in your settings, the correct thing to do would be to use{{ MEDIA_URL }}
.