Django MEDIA_URL e MEDIA_ROOT

229

Estou tentando fazer upload de uma imagem através do administrador do Django e, em seguida, visualizá-la em uma página no frontend ou apenas através de um URL.

Observe que tudo isso está na minha máquina local.

Minhas configurações são as seguintes:

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

MEDIA_URL = '/media/'

Eu configurei o parâmetro upload_to como 'images' e o arquivo foi carregado corretamente no diretório:

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

No entanto, quando tento acessar a imagem no seguinte URL:

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

Eu recebo um erro 404.

Preciso configurar padrões URLconf específicos para a mídia carregada?

Qualquer conselho apreciado.

Obrigado.

Dan
fonte

Respostas:

293

ATUALIZAÇÃO para Django> = 1.7

Por documentação do Django 2.1: servindo arquivos carregados por um usuário durante o desenvolvimento

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)

Você não precisa mais, if settings.DEBUGpois o Django cuidará para garantir que isso seja usado apenas no modo Debug.


Resposta ORIGINAL para Django <= 1.6

Tente colocar isso em seus 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}))

Com isso, você pode servir a mídia estática do Django quando DEBUG = True(quando você executa no computador local), mas pode permitir que a configuração do servidor da web atenda a mídia estática quando você vai para produção eDEBUG = False

Micah Carrick
fonte
14
PS. Então você pode usar isso em seus modelos: <img src = "{{MEDIA_URL}} imagens / myimage.png" />
Micah Carrick
Eu não acho que é bom adicionar ^sinal antes media//(?P<path>.*)$, em algum momento quando acessamos o arquivo de mídia no caminho do URL do aplicativo (como http://127.0.0.1:8000/myapp/media/img/logo.png), esse regular não é matemático.
Jack Zhang
Estou lutando há 2 dias porque minhas imagens retornam 404. Essa é a única coisa que sinto falta e não consigo encontrá-la no Django doc. Obrigado.
tambalolo
1
Se você estiver usando o Django 1.5+, veja a resposta abaixo; é uma solução melhor.
Thane Brimhall
isso está no seu aplicativo ou projeto urls.py?
user7804781
105

Leia o DOC oficial do Django com atenção e você encontrará a resposta mais adequada.

A melhor e mais fácil maneira de resolver isso é como abaixo.

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___
fonte
1
É um novo recurso adicionado no django 1.5
codeVerine 31/07
está tudo bem em usá-lo dessa maneira na produção com apache?
andilabs
1
@andi - Não, não é permitido usá-lo dessa maneira na produção. Ele deve ser configurado via apache em sua produção.
Vikas Gulati
1
Mas não há problema em deixar esse código aqui em produção sem if settings.DEVverificação porque ele é desativado automaticamente?
jozxyqk
70

Para o Django 1.9, você precisa adicionar o seguinte código conforme a documentação:

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 obter mais informações, você pode consultar aqui: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development

thisisashwani
fonte
2
Esta é a solução para django> 1.9, thnks.
precisa saber é
13
Apenas certifique-se de colocar isso nos urls.py do seu projeto e não do seu aplicativo, o que eu fiz acidentalmente.
28416 Jarno
3
Trabalhou para mim na 1.10 também.
Deleet 17/08
Nao funciona para mim. Talvez haja configurações subjacentes necessárias em settings.py?
Fusion
25

Aqui o que eu fiz no Django 2.0. Definir primeiro MEDIA_ROOT um MEDIA_URL emsetting.py

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

Em seguida, habilite o media context_processors em TEMPLATE_CONTEXT_PROCESSORSadicionando

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

Seu media context processorestá ativado. Agora, todos RequestContextconterão uma variávelMEDIA_URL .

Agora você pode acessar isso em seu template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>
Akhilendra
fonte
maravilhosamente explicado - esta foi a resposta para mim. A chave foi adicionar o processador de contexto de mídia .
21819 David Maness
23

Preciso configurar padrões URLconf específicos para a mídia carregada?

Sim. Para o desenvolvimento, é tão fácil quanto adicionar isso ao seu URLconf:

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

No entanto, para produção, você desejará veicular a mídia usando Apache, lighttpd, nginx ou seu servidor da web preferido.

mipadi
fonte
3
O que isso significa como você configura o servidor?
M Hornbacher
Eu recebo uma referência não resolvida a "padrões", isso é importado de algum lugar?
user7804781
6

(pelo menos) para o Django 1.8:

Se você usar

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

como descrito acima, verifique se nenhum padrão de URL "pegar todos", direcionado para uma exibição padrão, é anterior ao urlpatterns = []. Como .append colocará o esquema adicionado no final da lista, é claro que só será testado se nenhum padrão de URL anterior corresponder. Você pode evitar isso usando algo assim, em que o padrão de URL "catch all" é adicionado no final, independente da instrução 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.
fonte
6

Aqui estão as alterações que eu tive que fazer para entregar PDFs para as publicações django aplicativo , usando o Django 1.10.6:

Utilizou as mesmas definições para diretórios de mídia que você, em settings.py:

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

MEDIA_URL = '/media/'

Conforme fornecido por @thisisashwanipandey, no principal do projeto 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)

e uma modificação da resposta fornecida por @ r-allela, em 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
fonte
4

Outro problema que você provavelmente enfrentará após configurar todos os seus padrões de URLconf é que a variável {{ MEDIA_URL }}não funcionará em seus modelos. Para corrigir isso, em seu settings.py , adicione

django.core.context_processors.media

no seu TEMPLATE_CONTEXT_PROCESSORS.

r_allela
fonte
2

Adicionando à Micah Carrick a resposta para o django 1.8:

if settings.DEBUG:
  urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))
user3894045
fonte
1
Não funciona para mim (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
Deleet 17/08/16
2

Isto é o que eu fiz para obter a renderização de imagem no modo DEBUG = False no Python 3.6 com o Django 1.11

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

Seguindo as etapas mencionadas acima para => 3.0 no modo Debug

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

E também a parte que me chamou a atenção, a URL estática acima funcionou apenas no meu arquivo urls.py do projeto principal.Eu estava tentando primeiro adicionar ao meu aplicativo e me perguntando por que não conseguia ver as imagens.

Por fim, certifique-se de definir o seguinte:

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

Isso se for para o Django 1.10:

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

Sua configuração está correta. Alguns servidores da Web exigem a especificação específica dos arquivos de mídia e pasta estática. Por exemplo, em pythonanywhere.com, você deve ir para a seção 'Web' e adicionar o URL das pastas de mídia e pasta estática. Por exemplo:

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

Eu sei que é tarde, mas apenas para ajudar quem visita este link por causa do mesmo problema;)

Saidmamad
fonte