Django MEDIA_URL et MEDIA_ROOT

229

J'essaie de télécharger une image via l'administrateur Django, puis de visualiser cette image dans une page sur le frontend ou simplement via une URL.

Notez que tout cela est sur ma machine locale.

Mes paramètres sont les suivants:

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

MEDIA_URL = '/media/'

J'ai défini le paramètre upload_to sur 'images' et le fichier a été correctement téléchargé dans le répertoire:

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

Cependant, lorsque j'essaie d'accéder à l'image à l'URL suivante:

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

J'obtiens une erreur 404.

Dois-je configurer des patrons URLconf spécifiques pour les médias téléchargés?

Tout conseil apprécié.

Merci.

Dan
la source

Réponses:

293

MISE À JOUR pour Django> = 1.7

Selon la documentation de Django 2.1: Servir les fichiers téléchargés par un utilisateur pendant le développement

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)

Vous n'en avez plus besoin if settings.DEBUGcar Django se chargera de s'assurer que cela n'est utilisé qu'en mode débogage.


Réponse ORIGINALE pour Django <= 1.6

Essayez de mettre cela dans votre 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}))

Avec cela, vous pouvez servir les supports statiques de Django lorsque DEBUG = True(lorsque vous exécutez sur un ordinateur local) mais vous pouvez laisser votre configuration de serveur Web servir des supports statiques lorsque vous passez en production etDEBUG = False

Micah Carrick
la source
14
PS. Vous pouvez ensuite utiliser ceci dans vos modèles: <img src = "{{MEDIA_URL}} images / myimage.png" />
Micah Carrick
Je ne pense pas qu'il soit bon d'ajouter un ^signe avant media//(?P<path>.*)$, parfois lorsque nous accédons au fichier multimédia dans le chemin de l'URL de l'application (comme http://127.0.0.1:8000/myapp/media/img/logo.png), ce habituel ne fera pas de calcul.
Jack Zhang
J'ai du mal depuis 2 jours maintenant pourquoi mes images retournent 404. C'est la seule chose qui me manque et je ne la trouve pas dans la doc Django. Merci.
tambalolo
1
Si vous utilisez Django 1.5+, veuillez voir la réponse ci-dessous; c'est une meilleure solution.
Thane Brimhall
est-ce dans votre application ou votre projet urls.py?
user7804781
105

Veuillez lire attentivement le DOC officiel de Django et vous trouverez la réponse la plus appropriée.

La façon la plus simple et la plus simple de résoudre ce problème est la suivante.

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___
la source
1
C'est une nouvelle fonctionnalité ajoutée dans django 1.5
codeVerine
est-il acceptable de l'utiliser de cette façon en production avec apache?
andilabs
1
@andi - Non, ce n'est pas correct de l'utiliser de cette façon dans la production. Il doit être configuré via apache sur votre production.
Vikas Gulati
1
Mais est-ce OK de laisser ce code ici en production sans if settings.DEVvérification car il est désactivé automatiquement?
jozxyqk
70

Pour Django 1.9, vous devez ajouter le code suivant selon la documentation:

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)

Pour plus d'informations, vous pouvez vous référer ici: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development

thisisashwani
la source
2
C'est la solution pour django> 1.9, thnks.
unixeO
13
Assurez-vous simplement de mettre cela dans l'urls.py de votre projet et non de votre application, ce que j'ai accidentellement fait.
Jarno
3
A aussi fonctionné pour moi sur 1.10.
Deleet
ne fonctionne pas pour moi. Peut-être y a-t-il des paramètres sous-jacents nécessaires dans settings.py?
Fusion
25

Voici ce que j'ai fait dans Django 2.0. Définissez d'abord MEDIA_ROOT sur MEDIA_URL danssetting.py

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

Activez ensuite l'entrée media context_processors en TEMPLATE_CONTEXT_PROCESSORSajoutant

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

Votre media context processorest activé, maintenant chacun RequestContextcontiendra une variable MEDIA_URL.

Vous pouvez maintenant y accéder dans votre template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>
Akhilendra
la source
merveilleusement expliqué - c'était la réponse pour moi. La clé était d' ajouter le processeur de contexte multimédia .
David Maness
23

Dois-je configurer des patrons URLconf spécifiques pour les médias téléchargés?

Oui. Pour le développement, c'est aussi simple que d'ajouter ceci à votre URLconf:

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

Cependant, pour la production, vous voudrez servir les médias en utilisant Apache, lighttpd, nginx ou votre serveur Web préféré.

mipadi
la source
3
Qu'est-ce que cela signifie, comment configurez-vous le serveur?
M Hornbacher
J'obtiens une référence non résolue aux "modèles", est-ce importé de quelque part?
user7804781
6

(au moins) pour Django 1.8:

Si tu utilises

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

comme décrit ci-dessus, assurez-vous qu'aucun modèle d'URL "catch all", dirigeant vers une vue par défaut, ne précède dans urlpatterns = []. Comme .append mettra le schéma ajouté à la fin de la liste, il ne sera bien sûr testé que si aucun modèle d'URL précédent ne correspond. Vous pouvez éviter cela en utilisant quelque chose comme ceci où le modèle d'URL "catch all" est ajouté à la toute fin, indépendamment de l'instruction 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.
la source
6

Voici les changements que j'ai dû apporter pour livrer des PDF pour les publications django , en utilisant Django 1.10.6:

Utilisé les mêmes définitions pour les répertoires multimédias que vous, dans settings.py:

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

MEDIA_URL = '/media/'

Comme fourni par @thisisashwanipandey, dans le principal du projet 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)

et une modification de la réponse fournie par @ 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
la source
4

Un autre problème auquel vous serez probablement confronté après avoir configuré tous vos modèles de configuration d'URL est que la variable {{ MEDIA_URL }}ne fonctionnera pas dans vos modèles. Pour résoudre ce problème, dans votre settings.py , assurez-vous d'ajouter

django.core.context_processors.media

dans votre TEMPLATE_CONTEXT_PROCESSORS.

r_allela
la source
2

Ajout à la réponse de Micah Carrick pour Django 1.8:

if settings.DEBUG:
  urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))
user3894045
la source
1
Ne fonctionne pas pour moi (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
Deleet
2

C'est ce que j'ai fait pour obtenir un rendu d'image en mode DEBUG = False en Python 3.6 avec Django 1.11

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

En suivant les étapes mentionnées ci-dessus pour => 3.0 pour le mode débogage

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

Et aussi la partie qui m'a rattrapé, l'URL statique ci-dessus ne fonctionnait que dans mon fichier urls.py de projet principal.J'essayais d'abord d'ajouter à mon application et je me demandais pourquoi je ne pouvais pas voir les images.

Enfin, assurez-vous de définir les éléments suivants:

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

Si pour Django 1.10:

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

Votre réglage est correct. Certains serveurs Web nécessitent de spécifier spécifiquement les fichiers multimédias et les dossiers statiques. Par exemple, dans pythonanywhere.com, vous devez vous rendre dans la section «Web» et ajouter l'url des dossiers multimédias et du dossier statique. Par exemple:

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

Je sais qu'il est tard, mais juste pour aider ceux qui visitent ce lien à cause du même problème;)

Saidmamad
la source