ChatGPT解决这个技术问题 Extra ChatGPT

Django MEDIA_URL and MEDIA_ROOT

I'm trying to upload an image via the Django admin and then view that image either in a page on the frontend or just via a URL.

Note this is all on my local machine.

My settings are as follows:

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

MEDIA_URL = '/media/'

I have set the upload_to parameter to 'images' and the file has been correctly uploaded to the directory:

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

However, when I try to access the image at the following URL:

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

I get a 404 error.

Do I need to setup specific URLconf patters for uploaded media?

Any advice appreciated.

Thanks.


M
Micah Carrick

UPDATE for Django >= 1.7

Per Django 2.1 documentation: Serving files uploaded by a user during development

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)

You no longer need if settings.DEBUG as Django will handle ensuring this is only used in Debug mode.

ORIGINAL answer for Django <= 1.6

Try putting this into your 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}))

With this you can serve the static media from Django when DEBUG = True (when you run on local computer) but you can let your web server configuration serve static media when you go to production and DEBUG = False


PS. You can then use this in your templates:
I don't think it's good to add ^ sign before media//(?P<path>.*)$, sometime when we access media file in app url path (like http://127.0.0.1:8000/myapp/media/img/logo.png), this regular won't math.
I've been struggling for 2 days now why my images return 404. This is the only thing I'm missing and I can't find it in Django doc. Thanks.
If you're using Django 1.5+, please see the answer below; it is a better solution.
is this in your app or project urls.py?
B
Bhargav Rao

Please read the official Django DOC carefully and you will find the most fit answer.

The best and easist way to solve this is like below.

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)

It is a new feature added in django 1.5
is it ok to use it this way in production with apache?
@andi - No its not okay to use it this way in production. It should be configured via apache on your production.
But it's OK to leave this code here in production with no if settings.DEV check because it's disabled automatically?
t
thisisashwani

For Django 1.9, you need to add the following code as per the documentation :

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)

For more info, you can refer here : https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development


This is the solution for django >1.9, thnks.
Just make sure to put this into the urls.py of your project and not of your app, what I accidentally did.
Worked for me on 1.10 too.
does not work for me. Perhaps there are any necesary underlying settings in settings.py?
A
Akhilendra

Here What i did in Django 2.0. Set First MEDIA_ROOT an MEDIA_URL in setting.py

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

Then Enable the media context_processors in TEMPLATE_CONTEXT_PROCESSORS by adding

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

Your media context processor is enabled, Now every RequestContext will contain a variable MEDIA_URL.

Now you can access this in your template_name.html

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

wonderfully explained -- this was the answer for me. The key was adding the media context processor.
very nice context_processors tip
m
mipadi

Do I need to setup specific URLconf patters for uploaded media?

Yes. For development, it's as easy as adding this to your URLconf:

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

However, for production, you'll want to serve the media using Apache, lighttpd, nginx, or your preferred web server.


What does that mean how do you configure the server?
I get an unresolved reference to "patterns", is that imported from somewhere?
S
S. Ju.

(at least) for Django 1.8:

If you use

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

as described above, make sure that no "catch all" url pattern, directing to a default view, comes before that in urlpatterns = []. As .append will put the added scheme to the end of the list, it will of course only be tested if no previous url pattern matches. You can avoid that by using something like this where the "catch all" url pattern is added at the very end, independent from the if statement:

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')),

A
Alex Willison

Here are the changes I had to make to deliver PDFs for the django-publications app, using Django 1.10.6:

Used the same definitions for media directories as you, in settings.py:

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

MEDIA_URL = '/media/'

As provided by @thisisashwanipandey, in the project's main 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)

and a modification of the answer provided by @r-allela, in 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',
            ],
         },
    },
]

v
vishes_shell

Another problem you are likely to face after setting up all your URLconf patterns is that the variable {{ MEDIA_URL }} won't work in your templates. To fix this,in your settings.py, make sure you add

django.core.context_processors.media

in your TEMPLATE_CONTEXT_PROCESSORS.


This is better option but 'django.template.context_processors.media' worked for me
G
Gavin

Following the steps mentioned above for =>3.0 for Debug mode

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

And also the part that caught me out, the above static URL only worked in my main project urls.py file. I was first attempting to add to my app, and wondering why I couldn't see the images.

Lastly make sure you set the following:

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

A
Alok Kumar Maurya

If you'r using python 3.0+ then configure your project as below

Setting

STATIC_DIR = BASE_DIR / 'static'
MEDIA_DIR = BASE_DIR / 'media'
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'

Main Urls

from django.conf import settings
from django.conf.urls.static import static

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

u
user3894045

Adding to Micah Carrick answer for django 1.8:

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

Does not work for me (1.10). TypeError: view must be a callable or a list/tuple in the case of include()..
J
Jose Luis Quichimbo

This if for Django 1.10:

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

c
comiventor

This is what I did to achieve image rendering in DEBUG = False mode in Python 3.6 with Django 1.11

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

M
Madhav Dhungana

On production environment Django does not load the media root automatically so that we can overcome that issue by adding following codes right after URL patterns:

urlpatterns = [
       ''''
         your urls
       ''''
    ] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL,
                              document_root=settings.MEDIA_ROOT)

If you are using more than one app and if you are including app urls on main app url, just add this code(configuration) on main project URL.


S
Saidmamad

Your setting is all right. Some web servers require to specify the media and static folder files specifically. For example in pythonanywhere.com you have to go to the 'Web' section and add the url od the media folders and static folder. For example:

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

I know that it is late, but just to help those who visit this link because of the same problem ;)


N
Nick

For Django 3.0+ in development have the below in your main urls.py:

urlpatterns = [
   # rest of your url paths here..
]

from django.conf import settings
from django.conf.urls.static import static

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

K
Kai - Kazuya Ito

Add this code below to "settings.py" to access(open or display)uploaded files:

# "settings.py"

from django.conf import settings
from django.conf.urls.static import static

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