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

ฉันจำเป็นต้องตั้งค่า patric 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 จะจัดการให้มั่นใจว่าจะใช้เฉพาะในโหมดดีบั๊ก


คำตอบเดิมสำหรับ Django <= 1.6

ลองใส่สิ่งนี้ลงในURLของคุณ

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) ปกตินี้ไม่ได้คณิตศาสตร์
Jack Zhang

ฉันดิ้นรนมา 2 วันแล้วทำไมภาพของฉันถึง 404 นี่เป็นสิ่งเดียวที่ฉันหายไปและฉันหามันไม่เจอใน Django doc ขอบคุณ
tambalolo

1
หากคุณใช้ Django 1.5+ โปรดดูคำตอบด้านล่าง มันเป็นทางออกที่ดีกว่า
Thane Brimhall

อยู่ในแอปพลิเคชันหรือโครงการของคุณหรือไม่
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

มันโอเคที่จะใช้วิธีนี้ในการผลิตด้วย Apache หรือไม่?
andilabs

1
@andi - ไม่เป็นไรที่จะใช้วิธีนี้ในการผลิต ควรกำหนดค่าผ่าน apache ในการผลิตของคุณ
Vikas Gulati


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
เพียงให้แน่ใจว่าใส่สิ่งนี้ลงใน URL ของโครงการของคุณไม่ใช่แอปของคุณสิ่งที่ฉันตั้งใจทำ
Jarno

3
ทำงานให้ฉันในวันที่ 1.10 ด้วย
Deleet

ไม่ได้ผลสำหรับฉัน อาจมีการตั้งค่าพื้นฐานที่จำเป็นใน settings.py?
ฟิวชั่น

25

นี่ฉันทำอะไรใน Django 2.0 ตั้งค่า MEDIA_ROOT แรกให้เป็น MEDIA_URLsetting.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ถูกเปิดใช้งานตอนนี้ทุกจะมีตัวแปรRequestContextMEDIA_URL

ตอนนี้คุณสามารถเข้าถึงสิ่งนี้ได้ในของคุณ template_name.html

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

อธิบายอย่างมหัศจรรย์ - นี่คือคำตอบสำหรับฉัน ที่สำคัญคือการเพิ่มหน่วยประมวลผลบริบทสื่อ
David Maness

23

ฉันจำเป็นต้องตั้งค่า patric 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

ฉันได้รับการอ้างอิงถึง "รูปแบบ" ที่ไม่ได้แก้ไขที่นำเข้ามาจากที่อื่นหรือไม่
user7804781

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 = [] ในฐานะ. ผนวกจะนำรูปแบบที่เพิ่มไปยังจุดสิ้นสุดของรายการมันแน่นอนว่าจะมีการทดสอบเฉพาะถ้าไม่มีรูปแบบ URL ก่อนหน้านี้ที่ตรงกัน คุณสามารถหลีกเลี่ยงสิ่งนั้นได้โดยใช้บางสิ่งเช่นนี้ซึ่งมีการเพิ่มรูปแบบ URL "จับทั้งหมด" ไว้ท้ายสุดโดยไม่ขึ้นกับคำสั่ง 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-โดยใช้ 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

การเพิ่มคำตอบ Micah Carrick สำหรับ django 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 ใน 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 คุณต้องไปที่ส่วน 'เว็บ' และเพิ่ม URL ในโฟลเดอร์สื่อและโฟลเดอร์คงที่ ตัวอย่างเช่น:

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

ฉันรู้ว่ามันสาย แต่เพียงเพื่อช่วยผู้ที่เข้าชมลิงก์นี้เนื่องจากปัญหาเดียวกัน;)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.