AME
AME

Reputation: 339

Image Failure in Django Blog

I've created a simple django blog, and I'm having trouble getting images to consistently show up in my posts. Specifically, my images appear in the "list" view (the home page for the site), but not in the "detail" view (when viewing one individual post). The website is here if you want to see the issue live: endicott.co

The code for the list view is below:

{% extends "blog/base.html" %}

{% block title %}endicott.co{% endblock %}

{% block content %}
<div class="page-header">
    <h1>endicott.co</h1>
    <p>Perspectives on society, data, and economics</p>
</div>

    {% for post in posts %}
        <h2>
            <a href="{{ post.get_absolute_url }}">
                {{ post.title }}
            </a>
        </h2>
        <p class="date">
            Published {{ post.publish }} by {{ post.author }}
        </p>
        <img src="{{ post.image.url }}" alt="img">
        {{ post.body|linebreaks }}
    {% endfor %}
    {% include "pagination.html" with page=page_obj %}
{% endblock %}

The code for the detail view is listed below:

{% extends "blog/base.html" %}

{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    <h1>{{ post.title }}</h1>
    <img src="{{ post.image.url }}" alt="img">
    <p class="date">
        Published {{ post.publish }} by {{ post.author }}
    </p>
    {{ post.body|linebreaks }}
{% endblock %}

Any thoughts on why django is correctly showing the image in the list but not the detail view? Let me know if I should post any additional code for more background.

The file structure is as follows:

blog/
-__pycache__/
-migrations/
-templates/
--blog/
---post/
----detail.html
----list.html
---base.html
--pagination.html
-__init__.py
-admin.py
-apps.py
-models.py
-tests.py
-urls.py
-view.py
media/
-img/
--[where images are stored]
mysite/
-__pycache__/
-static/
-__init__.py
-settings.py
-urls.py
-wsgi.py

My blog urls.py file is below:

from django.conf.urls import url
from . import views



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



urlpatterns = [
    # post views
    #url(r'^$', views.post_list, name='post_list'),
    url(r'^$', views.PostListView.as_view(), name='post_list'),
    url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/'\
        r'(?P<post>[-\w]+)/$',
        views.post_detail,
        name='post_detail'),
]




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

The mysite urls.py file is below:

from django.conf.urls import include, url
from django.contrib import admin

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


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', include('blog.urls',
                          namespace='blog',
                          app_name='blog')),
]



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

Upvotes: 2

Views: 58

Answers (1)

grochmal
grochmal

Reputation: 3027

Your problem is that the src= is understood as a relative URL (just like saq7 pointed). You want the image to have its src= pointing to an absolute URL (starting with http://) since the image sits at an absolute location from the website root (from the domain).

To perform that, you shall use {% media post.image.url %}. Note that for that you need to perform a couple of additions to settings.py, notably MEDIA_ROOT and MEDIA_URL, in order for the {% media %} template tag to work.

Using media files in this fashion (with {% media %}) is the most common and accepted way. Note that in production (i.e. behind a real webserver) such files shall not be server by Django, note how that article has:

This is not suitable for production use!

Yet, there is another article in the Django documentation explaining what to do to configure your webserver to serve these files.


Also, if you set MEDIA_URL = '/media/' you will need to remove the media/ prefix from post.image.url.

Upvotes: 2

Related Questions