Django MEDIA_URL y MEDIA_ROOT

229

Estoy tratando de cargar una imagen a través del administrador de Django y luego ver esa imagen en una página en la interfaz o simplemente a través de una URL.

Tenga en cuenta que todo esto está en mi máquina local.

Mi configuración es la siguiente:

MEDIA_ROOT = '/home/dan/mysite/media/'

MEDIA_URL = '/media/'

Establecí el parámetro upload_to en 'imágenes' y el archivo se cargó correctamente en el directorio:

'/home/dan/mysite/media/images/myimage.png'

Sin embargo, cuando intento acceder a la imagen en la siguiente URL:

http://127.0.0.1:8000/media/images/myimage.png

Me sale un error 404.

¿Debo configurar patrones específicos de URLconf para los medios cargados?

Cualquier consejo apreciado.

Gracias.

Dan
fuente

Respuestas:

293

ACTUALIZACIÓN para Django> = 1.7

Según la documentación de Django 2.1: Sirviendo archivos cargados por un usuario durante el desarrollo

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Ya no necesita, if settings.DEBUGya que Django se encargará de garantizar que esto solo se use en modo de depuración.


Respuesta ORIGINAL para Django <= 1.6

Intenta poner esto en tus urls.py

from django.conf import settings

# ... your normal urlpatterns here

if settings.DEBUG:
    # static files (images, css, javascript, etc.)
    urlpatterns += patterns('',
        (r'^media/(?P<path>.*)$', 'django.views.static.serve', {
        'document_root': settings.MEDIA_ROOT}))

Con esto, puede servir los medios estáticos de Django cuando DEBUG = True(cuando se ejecuta en una computadora local) pero puede dejar que la configuración de su servidor web sirva los medios estáticos cuando vaya a producción yDEBUG = False

Micah Carrick
fuente
14
PD. Luego puede usar esto en sus plantillas: <img src = "{{MEDIA_URL}} images / myimage.png" />
Micah Carrick
No creo que sea bueno agregar un ^signo antes media//(?P<path>.*)$, en algún momento cuando accedemos al archivo multimedia en la ruta de la url de la aplicación (como http://127.0.0.1:8000/myapp/media/img/logo.png), esto no es matemático.
Jack Zhang
He estado luchando durante 2 días por qué mis imágenes devuelven 404. Esto es lo único que me falta y no puedo encontrarlo en Django doc. Gracias.
tambalolo
1
Si está utilizando Django 1.5+, consulte la respuesta a continuación; Es una mejor solución.
Thane Brimhall
¿está esto en su aplicación o proyecto urls.py?
user7804781
105

Lea atentamente el DOC oficial de Django y encontrará la respuesta más adecuada.

La mejor y más fácil forma de resolver esto es la siguiente.

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
JChen___
fuente
1
Es una nueva característica agregada en django 1.5
codeVerine
¿Está bien usarlo de esta manera en producción con apache?
andilabs
1
@andi - No, no está bien usarlo de esta manera en la producción. Debe configurarse a través de apache en su producción.
Vikas Gulati
1
¿Pero está bien dejar este código aquí en producción sin if settings.DEVverificación porque se desactiva automáticamente?
jozxyqk 01 de
70

Para Django 1.9, debe agregar el siguiente código según la documentación:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Para obtener más información, puede consultar aquí: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development

thisisashwani
fuente
2
Esta es la solución para django> 1.9, gracias.
unixeO
13
Solo asegúrate de poner esto en el urls.py de tu proyecto y no de tu aplicación, lo que accidentalmente hice.
Jarno
3
También me funcionó en 1.10.
Deleet
no funciona para mi ¿Quizás haya alguna configuración subyacente necesaria en settings.py?
Fusion
25

Aquí lo que hice en Django 2.0. Establecer primero MEDIA_ROOT un MEDIA_URL ensetting.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'data/') # 'data' is my media folder
MEDIA_URL = '/media/'

A continuación, Habilitar el media context_processors en TEMPLATE_CONTEXT_PROCESSORSañadiendo

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            #here add your context Processors
            'django.template.context_processors.media',
        ],
    },
},
]

Su media context processorestá habilitado, ahora cada RequestContextcontendrá una variable MEDIA_URL.

Ahora puedes acceder a esto en tu template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>
Akhilendra
fuente
maravillosamente explicado: esta fue la respuesta para mí. La clave fue agregar el procesador de contexto de medios .
David Maness
23

¿Debo configurar patrones específicos de URLconf para los medios cargados?

Si. Para el desarrollo, es tan fácil como agregar esto a su URLconf:

if settings.DEBUG:
    urlpatterns += patterns('django.views.static',
        (r'media/(?P<path>.*)', 'serve', {'document_root': settings.MEDIA_ROOT}),
    )

Sin embargo, para la producción, querrás servir los medios usando Apache, lighttpd, nginx o tu servidor web preferido.

mipadi
fuente
3
¿Qué significa eso cómo configurar el servidor?
M Hornbacher
Me sale una referencia no resuelta a "patrones", ¿eso se importa de alguna parte?
user7804781
6

(al menos) para Django 1.8:

Si utiliza

if settings.DEBUG:
  urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))

como se describió anteriormente, asegúrese de que no aparezca ningún patrón de URL "capturar todo", que dirija a una vista predeterminada, antes de eso en urlpatterns = []. Como .append colocará el esquema agregado al final de la lista, por supuesto solo se probará si no coincide ningún patrón de URL anterior. Puede evitarlo usando algo como esto donde el patrón de URL "catch all" se agrega al final, independientemente de la instrucción if:

if settings.DEBUG:
    urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))

urlpatterns.append(url(r'$', 'views.home', name='home')),
S. Ju.
fuente
6

Estos son los cambios que tuve que hacer para entregar archivos PDF para la aplicación de publicaciones django , usando Django 1.10.6:

Usó las mismas definiciones para directorios de medios que usted, en settings.py:

MEDIA_ROOT = '/home/user/mysite/media/'

MEDIA_URL = '/media/'

Según lo provisto por @thisisashwanipandey, en lo principal del proyecto urls.py :

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

y una modificación de la respuesta proporcionada por @ r-allela, en settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                # ... the rest of your context_processors goes here ...
                'django.template.context_processors.media',
            ],
         },
    },
]
Alex Willison
fuente
4

Otro problema que probablemente enfrentará después de configurar todos sus patrones de URLconf es que la variable {{ MEDIA_URL }}no funcionará en sus plantillas. Para solucionar esto, en settings.py , asegúrate de agregar

django.core.context_processors.media

en su TEMPLATE_CONTEXT_PROCESSORS.

r_allela
fuente
2

Agregando a la respuesta de Micah Carrick para django 1.8:

if settings.DEBUG:
  urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))
usuario3894045
fuente
1
No funciona para mí (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
Deleet
2

Esto es lo que hice para lograr la representación de la imagen en DEBUG = False mode en Python 3.6 con Django 1.11

from django.views.static import serve
urlpatterns = [
url(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
# other paths
]
comentarista
fuente
2

Siguiendo los pasos mencionados anteriormente para => 3.0 para el modo de depuración

urlpatterns = [
...
]
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Y también la parte que me sorprendió, la URL estática anterior solo funcionó en mi archivo principal del proyecto urls.py.Primero intentaba agregar a mi aplicación y me preguntaba por qué no podía ver las imágenes.

Por último, asegúrese de configurar lo siguiente:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Gavin
fuente
1

Esto si para Django 1.10:

 if settings.DEBUG:
    urlpatterns += staticfiles_urlpatterns()
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Jose Luis Quichimbo
fuente
0

Tu configuración está bien. Algunos servidores web requieren especificar específicamente los archivos multimedia y los archivos de carpetas estáticas. Por ejemplo, en pythonanywhere.com debe ir a la sección 'Web' y agregar la url de las carpetas multimedia y la carpeta estática. Por ejemplo:

  URL                     Directory                
/static/            /home/Saidmamad/discoverthepamirs/static     
/accounts/static/   /home/Saidmamad/discoverthepamirs/accounts/static    
/media/            /home/Saidmamad/discoverthepamirs/discoverthepamirs/media    

Sé que es tarde, pero solo para ayudar a quienes visitan este enlace debido al mismo problema;)

Saidmamad
fuente