djangodjango-media

Django media url from model


I'm working on a simple blog, I have this model for the blog post:

class BlogPost(models.Model):
    title = models.CharField(max_length=150, unique=True)
    body = models.TextField()
    cover_image = models.ImageField(upload_to='blogposts/')
    created_on = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    category = models.ManyToManyField('PostCategory', related_name='posts')
    slug = models.SlugField(null=True, unique=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("blog_detail", kwargs={"slug": self.slug})

In the settings file, I have the following configuration for static and media files:

STATIC_URL = '/static/'
MEDIA_URL = '/media/'

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

I'm creating the blog models and views in a separate app I named "blog"

I'm using a Django classed-based list view to display the posts on the page:

class BlogListView(ListView):
    model = BlogPost
    template_name = "blog/blog_list.html"

And I have the URL files working just fine: The problem is in displaying it in my template view, primarily for the post's cover image:

{% for post in object_list %}
  <div class="single-blog-item style-2 d-flex flex-wrap align-items-center mb-50">
    <!-- Blog Thumbnail -->
    <div class="blog-thumbnail">
      <a href="{{ post.get_absolute_url }}">
        <img src="{{ post.cover_image }}" alt="">
      </a>
    </div>
    <!-- Blog Content -->
    <div class="blog-content">
      <a href="{{ post.get_absolute_url }}" class="post-title">{{ post.title }}</a>
      <p>We'll come back to this...</p>
      <div class="post-meta">
        <a href="#"><i class="icon_clock_alt"></i> {{ post.created_on }}</a>
        <a href="#"><i class="icon_chat_alt"></i> 3 Comments</a>
      </div>
    </div>
  </div>
{% endfor %}

Every other tag is working just fine except for the cover image. The {{ post.cover_image }} template tag is not displaying any image, after inspecting the page for one of the posts, I find it is linking to:

http://127.0.0.1:8000/blog/blogpost/12.png 

the page above doesn't exist, the image was actually uploaded to the media folder. Hence, the uploaded image from the model is found here:

http://127.0.0.1:8000/media/blogpost/12.png

but the {{ post.cover_image }} tag is linking elsewhere to the inexistent page below:

http://127.0.0.1:8000/blog/blogpost/12.png 

How do I resolve this to allow the tag link to the right location to display the correct image URL?


Solution

  • I figured out the answer from Ivan's comment;

    Using {{ post.cover_image }} does not render the URL of the image (or media file) generally, it only renders the file name and location in the media root.

    Hence,

    {{ post.cover_image }} = blogposts/12.png
    

    which automatically joins with the blog page URL to produce the inexistent link for the image shown in the post. However,

    {{ post.cover_image.url }}
    

    fixes this, with the .url addition, it renders the URL of the media file and displays it correctly.

    Thus:

    {{ post.cover_image.url }} = http://127.0.0.1:8000/media/blogpost/12.png
    

    This works fine!