Django MEDIA_URL та MEDIA_ROOT


229

Я намагаюся завантажити зображення через адміністратора Django, а потім переглядати це зображення або на сторінці на фронті, або просто через URL-адресу.

Зауважте, це все на моїй локальній машині.

Мої налаштування такі:

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

MEDIA_URL = '/media/'

Я встановив параметр upload_to на "images" і файл був правильно завантажений у каталог:

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

Однак, коли я намагаюся отримати доступ до зображення за такою URL-адресою:

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

Я отримую помилку 404.

Чи потрібно налаштувати певні URLconf малюнки для завантаженого носія?

Будь-яка рада оцінена.

Дякую.

Відповіді:


293

ОНОВЛЕННЯ для Django> = 1,7

Документація на Django 2.1: обслуговування файлів, завантажених користувачем під час розробки

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)

Вам більше не потрібно, if settings.DEBUGоскільки Django буде працювати, переконуючись, що це використовується лише в режимі налагодження.


ОРИГІНАЛЬНА відповідь на Джанго <= 1.6

Спробуйте вкласти це у свій 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}))

Завдяки цьому ви можете обслуговувати статичні носії від Django, коли DEBUG = True(коли ви працюєте на локальному комп'ютері), але ви можете дозволити конфігурації веб-сервера обслуговувати статичні носії, коли ви переходите до виробництва таDEBUG = False


14
PS. Потім ви можете використовувати це у своїх шаблонах: <img src = "{{MEDIA_URL}} images / myimage.png" />
Micah Carrick

Я не думаю, що раніше добре додавати ^знак media//(?P<path>.*)$, коли ми отримуємо доступ до медіафайлу в URL-адресі додатка (наприклад http://127.0.0.1:8000/myapp/media/img/logo.png), це звичайне значення не буде математичним.
Джек Чжан

Я боровся вже два дні, чому мої зображення повертаються 404. Це єдине, чого мені не вистачає, і я не можу його знайти в документі Django. Дякую.
tambalolo

1
Якщо ви використовуєте Django 1.5+, будь ласка, дивіться відповідь нижче; це краще рішення.
Thane Brimhall

це у вашому додатку чи проекті urls.py?
user7804781

105

Будь ласка уважно прочитайте офіційний Django DOC, і ви знайдете найбільш відповідну відповідь.

Найкращий і найясніший спосіб вирішити це, як показано нижче.

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)

1
Це нова функція, додана в django 1.5
codeVerine

це нормально використовувати його таким чином у виробництві з апачем?
andilabs

1
@andi - Ні, це не добре використовувати цей спосіб у виробництві. Це має бути налаштовано через apache на вашому виробництві.
Вікас Гулаті


1
Але це нормально залишати цей код тут у виробництві без if settings.DEVперевірки, оскільки він відключається автоматично?
jozxyqk

70

Для Django 1.9 вам потрібно додати наступний код відповідно до документації:

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)

Для отримання додаткової інформації можна звернутися тут: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development


2
Це рішення для django> 1.9, thnks.
unixeO

13
Просто переконайтеся, що ви це помістите у urls.py свого проекту, а не вашого додатка, що я випадково зробив.
Ярно

3
Працював для мене і на 1.10.
Deleet

не працює для мене. Можливо, в settings.py є якісь необхідні основні параметри?
Fusion

25

Ось що я зробив у Django 2.0. Встановіть MEDIA_ROOT першим у MEDIA_URL дюймаsetting.py

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

Потім включите media context_processors в TEMPLATE_CONTEXT_PROCESSORSшляхом додавання

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

Ваш media context processorвключений, тепер кожен RequestContextбуде містити змінну MEDIA_URL.

Тепер ви можете отримати доступ до цього у своєму template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>

чудово пояснив - це була відповідь для мене. Ключовим було додавання процесора медіа контексту .
Девід Манесс

23

Чи потрібно налаштувати певні URLconf малюнки для завантаженого носія?

Так. Для розробки це так само просто, як додати це до URLconf:

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

Однак для виробництва вам потрібно буде обслуговувати медіа за допомогою Apache, lighttpd, nginx або бажаного веб-сервера.


3
Що це означає, як налаштувати сервер?
M Hornbacher

Я отримую невирішене посилання на "шаблони", це імпорт звідкись?
користувач7804781

6

(принаймні) для Django 1.8:

Якщо ви використовуєте

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

як описано вище, переконайтеся, що жоден шаблон URL-адреси "зловити всіх", спрямований на перегляд за замовчуванням, не переходить до цього в urlpatterns = []. Оскільки .append додасть додану схему до кінця списку, вона, звичайно, буде перевірена лише у тому випадку, якщо попередній шаблон URL-адреси не збігається. Ви можете уникнути цього, використовуючи щось подібне, коли шаблон URL-адреси "catch all" додається в самому кінці, незалежно від оператора 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')),

6

Ось зміни, які мені довелося внести, щоб доставити PDF-файли для програми django-публікацій , використовуючи Django 1.10.6:

Використовували ті самі визначення для медіа-каталогів, що і ви, у settings.py:

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

MEDIA_URL = '/media/'

Як надає @thisisashwanipandey, в головному проекті 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)

і модифікація відповіді, наданої @ r-allela, у 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',
            ],
         },
    },
]

4

Ще одна проблема, з якою ви, мабуть, зіткнетесь після налаштування всіх шаблонів URLconf, полягає в тому, що змінна {{ MEDIA_URL }}не працюватиме у ваших шаблонах. Щоб це виправити, в вашому settings.py , переконайтеся , що ви додаєте

django.core.context_processors.media

у вашому TEMPLATE_CONTEXT_PROCESSORS.


2

Додавання Міхе Керріку відповіді за джанго 1,8:

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

1
Не працює для мене (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
Deleet

2

Це я зробив для досягнення візуалізації зображення в DEBUG = False mode в Python 3.6 з Django 1,11

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

2

Дотримуючись вищезазначених кроків для => 3.0 для режиму налагодження

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

А також частина, яка мене зловила, вказана вище статична URL-адреса працювала лише в моєму головному проекті urls.py. Я спершу намагався додати в свій додаток і цікавився, чому я не міг бачити зображення.

Нарешті, переконайтеся, що ви встановили наступне:

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


0

У вас все в порядку. Деякі веб-сервери вимагають конкретно вказати медіа та статичні файли папок. Наприклад, у pythonanywhere.com вам потрібно перейти до розділу "Web" і додати URL-адресу папок мультимедіа та статичну папку. Наприклад:

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

Я знаю, що вже пізно, але просто допомогти тим, хто відвідує це посилання через ту ж проблему;)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.