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)
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 beMEDIA_ROOT
and you'd appendImageField.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
...This uses the
views.serve
bit and should only be used inDEBUG
mode. It overrides the path to media files(django's term for user uploaded content likeImageField
). This will redirect those requests through theserve
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.As of at least Django 1.8, there is a helper function
static()
that will set this up for you and ensure that it only functions in debug mode.Your
urls.py
should look something like this:...to simply quote the documentation.
Make sure that your
MEDIA_URL
is set to a relative path like/media/
and that yourMEDIA_ROOT
is an absolute filesystem path like/home/foo/project/media
.