Django MEDIA_URL dan MEDIA_ROOT

229

Saya mencoba mengunggah gambar melalui admin Django dan kemudian melihat gambar itu di halaman di frontend atau hanya melalui URL.

Perhatikan ini semua di mesin lokal saya.

Pengaturan saya adalah sebagai berikut:

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

MEDIA_URL = '/media/'

Saya telah menetapkan parameter upload_to ke 'gambar' dan file telah diunggah dengan benar ke direktori:

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

Namun, ketika saya mencoba mengakses gambar di URL berikut:

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

Saya mendapatkan kesalahan 404.

Apakah saya perlu menyiapkan patters URLconf khusus untuk media yang diunggah?

Setiap saran dihargai.

Terima kasih.

Dan
sumber

Jawaban:

293

UPDATE untuk Django> = 1.7

Dokumentasi Per Django 2.1: Melayani file yang diunggah oleh pengguna selama pengembangan

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)

Anda tidak perlu lagi if settings.DEBUGkarena Django akan menangani memastikan ini hanya digunakan dalam mode Debug.


Jawaban ORIGINAL untuk Django <= 1.6

Coba masukkan ini ke urls.py Anda

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}))

Dengan ini, Anda dapat menayangkan media statis dari Django when DEBUG = True(saat Anda menjalankan di komputer lokal) tetapi Anda dapat membiarkan konfigurasi server web Anda menyajikan media statis saat Anda pergi ke produksi danDEBUG = False

Micah Carrick
sumber
14
PS. Anda kemudian dapat menggunakan ini di templat Anda: <img src = "{{MEDIA_URL}} images / myimage.png" />
Micah Carrick
Saya tidak berpikir itu baik untuk menambahkan ^tanda sebelumnya media//(?P<path>.*)$, kadang-kadang ketika kita mengakses file media di jalur url aplikasi (seperti http://127.0.0.1:8000/myapp/media/img/logo.png), ini biasa tidak akan matematika.
Jack Zhang
Saya telah berjuang selama 2 hari sekarang mengapa gambar saya kembali 404. Ini adalah satu-satunya hal yang saya lewatkan dan saya tidak dapat menemukannya di Django doc. Terima kasih.
tambalolo
1
Jika Anda menggunakan Django 1.5+, silakan lihat jawabannya di bawah ini; itu adalah solusi yang lebih baik.
Thane Brimhall
apakah ini di urls.py aplikasi atau proyek Anda?
user7804781
105

Silakan baca DOC resmi Django dengan hati-hati dan Anda akan menemukan jawaban yang paling pas.

Cara terbaik dan mudah untuk menyelesaikan ini adalah seperti di bawah ini.

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___
sumber
1
Ini adalah fitur baru yang ditambahkan di Django 1.5
codeVerine
apakah boleh menggunakan cara ini dalam produksi dengan apache?
andilabs
1
@andi - Tidak, tidak apa-apa untuk menggunakannya dengan cara ini dalam produksi. Ini harus dikonfigurasi melalui apache pada produksi Anda.
Vikas Gulati
1
Tapi tidak apa-apa meninggalkan kode ini di sini dalam produksi tanpa if settings.DEVcek karena dinonaktifkan secara otomatis?
jozxyqk
70

Untuk Django 1.9, Anda perlu menambahkan kode berikut sesuai dokumentasi:

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)

Untuk info lebih lanjut, Anda dapat merujuk di sini: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development

thisisashwani
sumber
2
Ini adalah solusi untuk Django> 1.9, terima kasih.
unixeO
13
Pastikan untuk memasukkan ini ke urls.py proyek Anda dan bukan aplikasi Anda, apa yang saya lakukan secara tidak sengaja.
Jarno
3
Bekerja untuk saya di 1,10 juga.
Menghapus
tidak bekerja untuk saya. Mungkin ada pengaturan mendasar yang diperlukan di settings.py?
Fusion
25

Inilah yang saya lakukan di Django 2.0. Setel MEDIA_ROOT Pertama menjadi MEDIA_URLsetting.py

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

Kemudian Aktifkan media context_processors in TEMPLATE_CONTEXT_PROCESSORSdengan menambahkan

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

Anda media context processordiaktifkan, Sekarang setiap RequestContextakan berisi variabelMEDIA_URL .

Sekarang Anda dapat mengakses ini di template_name.html

<p><img src="{{ MEDIA_URL }}/image_001.jpeg"/></p>
Akhilendra
sumber
menjelaskan dengan luar biasa - ini adalah jawaban untuk saya. Kuncinya adalah menambahkan prosesor konteks media .
David Maness
23

Apakah saya perlu menyiapkan patters URLconf khusus untuk media yang diunggah?

Iya. Untuk pengembangan, semudah menambahkan ini ke URLconf Anda:

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

Namun, untuk produksi, Anda ingin melayani media menggunakan Apache, lighttpd, nginx, atau server web pilihan Anda.

mipadi
sumber
3
Apa artinya itu bagaimana Anda mengkonfigurasi server?
M Hornbacher
Saya mendapatkan referensi yang belum terselesaikan untuk "pola", apakah itu diimpor dari suatu tempat?
user7804781
6

(setidaknya) untuk Django 1.8:

Jika Anda menggunakan

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

seperti yang dijelaskan di atas, pastikan bahwa tidak ada pola url "tangkap semua", yang mengarahkan ke tampilan default, muncul sebelum itu di urlpatterns = []. Karena .append akan menempatkan skema tambahan pada bagian akhir daftar, tentu saja akan diuji jika tidak ada pola url yang cocok sebelumnya. Anda dapat menghindari itu dengan menggunakan sesuatu seperti ini di mana pola url "tangkap semua" ditambahkan di bagian paling akhir, terlepas dari pernyataan 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.
sumber
6

Berikut adalah perubahan yang harus saya lakukan untuk mengirimkan PDF untuk publikasi Django aplikasi Django, menggunakan Django 1.10.6:

Menggunakan definisi yang sama untuk direktori media seperti Anda, di settings.py:

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

MEDIA_URL = '/media/'

Seperti yang disediakan oleh @thisisashwanipandey, dalam proyek utama 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)

dan modifikasi dari jawaban yang diberikan oleh @ r-allela, di 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
sumber
4

Masalah lain yang mungkin Anda hadapi setelah menyiapkan semua pola URLconf Anda adalah bahwa variabel {{ MEDIA_URL }}tidak akan berfungsi di template Anda. Untuk memperbaikinya, di settings.py Anda , pastikan Anda menambahkan

django.core.context_processors.media

di Anda TEMPLATE_CONTEXT_PROCESSORS.

r_allela
sumber
2

Menambahkan jawaban Micah Carrick untuk Django 1.8:

if settings.DEBUG:
  urlpatterns.append(url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))
pengguna3894045
sumber
1
Tidak bekerja untuk saya (1,10). TypeError: view must be a callable or a list/tuple in the case of include()..
Menghapus
2

Inilah yang saya lakukan untuk mencapai rendering gambar di DEBUG = Mode salah dengan Python 3.6 dengan Django 1.11

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

Mengikuti langkah-langkah yang disebutkan di atas untuk => 3.0 untuk mode Debug

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

Dan juga bagian yang menarik perhatian saya, URL statis di atas hanya berfungsi di file urls.py proyek utama saya.Saya pertama kali mencoba menambahkan ke aplikasi saya, dan bertanya-tanya mengapa saya tidak bisa melihat gambar.

Terakhir, pastikan Anda mengatur yang berikut:

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

Ini jika untuk Django 1.10:

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

Pengaturan Anda baik-baik saja. Beberapa server web perlu menentukan media dan file folder statis secara khusus. Sebagai contoh di pythonanywhere.com Anda harus pergi ke bagian 'Web' dan menambahkan url folder media dan folder statis. Sebagai contoh:

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

Saya tahu bahwa ini sudah terlambat, tetapi hanya untuk membantu mereka yang mengunjungi tautan ini karena masalah yang sama;)

Saidmamad
sumber