Django MEDIA_URL và MEDIA_ROOT


229

Tôi đang cố tải lên một hình ảnh thông qua quản trị viên Django và sau đó xem hình ảnh đó trong một trang trên lối vào hoặc chỉ qua một URL.

Lưu ý đây là tất cả trên máy cục bộ của tôi.

Cài đặt của tôi như sau:

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

MEDIA_URL = '/media/'

Tôi đã đặt tham số upload_to thành 'hình ảnh' và tệp đã được tải lên chính xác vào thư mục:

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

Tuy nhiên, khi tôi cố gắng truy cập hình ảnh tại URL sau:

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

Tôi gặp lỗi 404.

Tôi có cần phải thiết lập các patters URLconf cụ thể cho phương tiện được tải lên không?

Mọi lời khuyên đánh giá cao.

Cảm ơn.

Câu trả lời:


293

CẬP NHẬT cho Django> = 1.7

Theo tài liệu Django 2.1: Phục vụ các tệp được tải lên bởi người dùng trong quá trình phát triển

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)

Bạn không còn cần if settings.DEBUGvì Django sẽ xử lý đảm bảo điều này chỉ được sử dụng trong chế độ Gỡ lỗi.


Câu trả lời GỐC cho Django <= 1.6

Hãy thử đặt cái này vào url của bạn

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

Với điều này, bạn có thể phục vụ phương tiện tĩnh từ Django khi DEBUG = True(khi bạn chạy trên máy tính cục bộ) nhưng bạn có thể để cấu hình máy chủ web của mình phục vụ phương tiện tĩnh khi bạn đi vào sản xuất vàDEBUG = False


14
Tái bút Sau đó, bạn có thể sử dụng điều này trong các mẫu của mình: <img src = "{{MEDIA_URL}} hình ảnh / myimage.png" />
Micah Carrick

Tôi không nghĩ nên thêm ^dấu hiệu trước đây media//(?P<path>.*)$, đôi khi khi chúng ta truy cập tệp phương tiện trong đường dẫn url của ứng dụng (như http://127.0.0.1:8000/myapp/media/img/logo.png), điều này sẽ không trở thành toán học.
Jack Zhang

Bây giờ tôi đã vật lộn được 2 ngày vì sao hình ảnh của tôi trở lại 404. Đây là thứ duy nhất tôi thiếu và tôi không thể tìm thấy nó trong tài liệu Django. Cảm ơn.
tambalolo

1
Nếu bạn đang sử dụng Django 1.5+, vui lòng xem câu trả lời bên dưới; nó là một giải pháp tốt hơn
Thane Brimhall

cái này có trong ứng dụng hoặc dự án của bạn không?
user7804781

105

Vui lòng đọc kỹ Django DOC và bạn sẽ tìm thấy câu trả lời phù hợp nhất.

Cách tốt nhất và dễ dàng để giải quyết điều này là như dưới đây.

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
Đây là một tính năng mới được thêm vào trong django 1.5
codeVerine

Bạn có thể sử dụng nó theo cách này trong sản xuất với apache không?
andilabs

1
@andi - Không có gì là không ổn khi sử dụng nó theo cách này trong sản xuất. Nó nên được cấu hình thông qua apache trên sản phẩm của bạn.
Vikas Gulati


1
Nhưng bạn có thể để mã này ở đây trong sản xuất mà không cần if settings.DEVkiểm tra vì nó tự động bị tắt?
jozxyqk

70

Đối với Django 1.9, bạn cần thêm mã sau theo tài liệu:

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)

Để biết thêm thông tin, bạn có thể tham khảo tại đây: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development


2
Đây là giải pháp cho django> 1.9, thnks.
unixeO

13
Chỉ cần đảm bảo đặt cái này vào url của dự án của bạn chứ không phải ứng dụng của bạn, điều tôi vô tình làm.
Jarno

3
Làm việc cho tôi trên 1.10 quá.
Deleet

không làm việc cho tôi. Có lẽ có bất kỳ cài đặt cơ bản nào trong cài đặt ẩn?
Hợp nhất

25

Đây là những gì tôi đã làm trong Django 2.0. Đặt MEDIA_ROOT đầu tiên MEDIA_URL trongsetting.py

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

Sau đó Kích hoạt tính năng media context_processors trong TEMPLATE_CONTEXT_PROCESSORSbằng cách bổ sung

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

Của bạn đã media context processorđược bật, Bây giờ mỗi RequestContextsẽ chứa một biến MEDIA_URL.

Bây giờ bạn có thể truy cập này trong template_name.html

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

giải thích tuyệt vời - đây là câu trả lời cho tôi. Chìa khóa đã được thêm bộ xử lý bối cảnh truyền thông .
David Maness

23

Tôi có cần phải thiết lập các patters URLconf cụ thể cho phương tiện được tải lên không?

Đúng. Để phát triển, thật dễ dàng như thêm phần này vào URLconf của bạn:

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

Tuy nhiên, để sản xuất, bạn sẽ muốn phục vụ phương tiện truyền thông bằng cách sử dụng Apache, lighttpd, nginx hoặc máy chủ web ưa thích của bạn.


3
Điều đó có nghĩa là làm thế nào để bạn cấu hình máy chủ?
M Hornbacher

Tôi nhận được một tài liệu tham khảo chưa được giải quyết cho "mẫu", được nhập từ đâu đó?
user7804781

6

(ít nhất) cho Django 1.8:

Nếu bạn dùng

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

như được mô tả ở trên, hãy đảm bảo rằng không có mẫu url "bắt tất cả", hướng đến chế độ xem mặc định, đi trước mẫu đó trong urlpotypes = []. Vì .append sẽ đặt lược đồ đã thêm vào cuối danh sách, nên tất nhiên nó sẽ chỉ được kiểm tra nếu không có mẫu url nào phù hợp. Bạn có thể tránh điều đó bằng cách sử dụng một cái gì đó như thế này trong đó mẫu url "bắt tất cả" được thêm vào cuối, độc lập với câu lệnh 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

Dưới đây là những thay đổi tôi phải thực hiện để cung cấp các tệp PDF cho ứng dụng django-ấn phẩm , sử dụng Django 1.10.6:

Đã sử dụng các định nghĩa tương tự cho các thư mục phương tiện như bạn, trong settings.py:

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

MEDIA_URL = '/media/'

Như được cung cấp bởi @thisisashwanipandey, trong phần chính của dự án 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)

và sửa đổi câu trả lời được cung cấp bởi @ r-allela, trong 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

Một vấn đề khác mà bạn có thể gặp phải sau khi thiết lập tất cả các mẫu URL của bạn là biến {{ MEDIA_URL }}không hoạt động trong các mẫu của bạn. Để khắc phục điều này, trong cài đặt của bạn , hãy đảm bảo bạn thêm

django.core.context_ Processors.media

trong của bạn TEMPLATE_CONTEXT_PROCESSORS.


2

Thêm vào câu trả lời của Micah Carrick cho django 1.8:

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

1
Không làm việc cho tôi (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
Deleet

2

Đây là những gì tôi đã làm để đạt được kết xuất hình ảnh trong chế độ DEBUG = false trong Python 3.6 với Django 1.11

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

2

Làm theo các bước được đề cập ở trên cho => 3.0 cho chế độ Gỡ lỗi

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

Và cũng là phần khiến tôi hiểu ra, URL tĩnh ở trên chỉ hoạt động trong tệp urls.py của dự án chính của tôi. Lần đầu tiên tôi cố gắng thêm vào ứng dụng của mình và tự hỏi tại sao tôi không thể nhìn thấy hình ảnh.

Cuối cùng hãy chắc chắn rằng bạn đặt như sau:

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

1

Điều này nếu cho Django 1.10:

 if settings.DEBUG:
    urlpatterns += staticfiles_urlpatterns()
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0

Cài đặt của bạn là ổn. Một số máy chủ web yêu cầu chỉ định cụ thể các tệp thư mục phương tiện và tĩnh. Ví dụ: trong pythonanywhere.com, bạn phải truy cập phần 'Web' và thêm url od các thư mục phương tiện và thư mục tĩnh. Ví dụ:

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

Tôi biết rằng đã muộn, nhưng chỉ để giúp những người truy cập liên kết này vì cùng một vấn đề;)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.