Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
251 views
in Technique[技术] by (71.8m points)

python - How do I serve media files in a local Django environment?

I can upload an image through the admin page, but the image can not be found when I navigate to the url that is generated by django. (404 error) The files are being uploaded to the folder:

project_root/media/eventbanner/1/

I have tried multiple solutions but none seem to work for my situation. Django 1.10 is being run local on Ubuntu 16.04.

The url I get is:

http://localhost:8000/media/eventbanner/1/banner_image.jpg

Media root folder is located at:

/home/username/xxx/xxx/project_name/media

Code in HTML file:

<div class="banner-image">
  <img src="{{ event.eventbanner.banner_image.url }}"/>
</div>

url.py code:

from django.conf.urls import url, include
from django.contrib import admin
from . import views
from django.conf import settings
from django.conf.urls.static import static

app_name = 'events'

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^details/(?P<event_id>[0-9]+)/$', views.details, name='details'),
url(r'^details/(?P<event_id>[0-9]+)/addcomment/$', views.add_comment, name='add_comment'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

STATIC_URL = '/static/'
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static'),]

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

models.py

def validate_only_one_instance(obj):
    model = obj.__class__
    if (model.objects.count() > 0 and obj.id != model.objects.get().id):
        raise ValidationError("Can only create 1 %s instance" % model.__name__)

class EventBanner(models.Model):
    event = models.OneToOneField(Event, unique=True)
    banner_image = models.ImageField(upload_to=get_image_path, blank=True, null=True)

    def clean(self):
        validate_only_one_instance(self)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The real problem here is that there is no relationship between this url http://localhost:8000/media/eventbanner/1/banner_image.jpg and this location on disk /home/username/xxx/xxx/project_name/media.

In a production application you'd have a web server where you'd store your Media content, the serving URL would be MEDIA_ROOT and you'd append ImageField.url to this value to get a valid image path.

What you need here is to set up a web server for your media images. At first that sounds like a lot of work, but Django provides a shortcut...

Serving Files in Development

You have some work you need to do to have the media files served locally. It requires some changes to your urls.py ...

from django.conf import settings
from django.views.static import serve

# ... the rest of your URLconf goes here ...

if settings.DEBUG:
    urlpatterns += [
        url(r'^media/(?P<path>.*)$', serve, {
            'document_root': settings.MEDIA_ROOT,
        }),
    ]

This uses the views.serve bit and should only be used in DEBUG mode. It overrides the path to media files(django's term for user uploaded content like ImageField). This will redirect those requests through the serve view. Best I can tell this is a mini web server that will map those request routes to locations on disk and allow those locations to be reachable via HTTP urls.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...