Building A Blog Website With Django Part 6

Before doing this tutorial, make sure you finish 

part one Creating Django Project
part two Creating Super User and Backend Dashboard access
part three  ORM, Backend to CRUD Post, and Category.
part four  creating working Front End via templates and Views.
part five Using TinyMCE as text editor for post’s body

A thumbnail of a post is a small image that provides a visual representation of the post content. So how we are gonna make a thumbnail for out post in Django? First we talk about where to put our media files in Django. In Django projects, media files, such as images that user upload, suggested to be stored separately from static files (like CSS and JavaScript). A common approach is to create a “media” directory at the root level of the project.

To set this up, follow these steps:

In the root folder, in our case is “myblog” or the same folder as ‘manage.py’, create a new folder named “media”. Inside “media” folder create another folder named “images”. Put a random image inside folder “myblog/media/images” and named it “thumbnail_defaut.png”. This image file will be our default thumbnail if user doesn’t input any images a.k.a empty.

Configure “myblog/blogproject/settings.py and add the following lines (line 14, 19 and 20).

and these too inside TEMPLATES array (line 70).

Modify file “myblog/blog/models.py”.

from django.db import models
from tinymce.models import HTMLField  

class Category(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name_plural = "categories"

    def __str__(self):
        return self.name
    
class Post(models.Model):
    title = models.CharField(max_length=255)
    body = HTMLField()  #models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    last_modified_on = models.DateTimeField(auto_now=True)
    categories = models.ManyToManyField("Category", related_name="posts")
    image_file = models.ImageField(upload_to='images/', default='images/thumbnail_default.png')

    def __str__(self):
        return self.title    

Modify file “myblog/blog/views.py”.

from django.template import loader
from django.http import HttpResponse
from .models import Post, Category
from django.utils.html import format_html

def blog_index(request):
    template = loader.get_template('blog_index.html')
    posts = Post.objects.all()
    context = {
        "posts" : posts
    }
    return HttpResponse(template.render(context))

def blog_details(request, pk):
    template = loader.get_template('blog_details.html')
    post = Post.objects.get(pk=pk)
    postBody = post.body
    postThumbnail = post.image_file
    context = {
        "post" : post,
        "thumbnail" : postThumbnail,
    }
    return HttpResponse(template.render(context))

def blog_category(request, category):
    template = loader.get_template('blog_category.html')
    posts = Post.objects.filter(
        categories__name__contains=category
    ).order_by("-created_on")
    context = {
        "category": category,
        "posts": posts,
    }
    return HttpResponse(template.render(context))

Modify file “myblog/blog/views.py”.

{% extends "base.html" %}

{% block page_content %}

<div class="container-md my-5">

{% block post %}
<article class="blog-post">
    <img class="mb-5" src="{{ thumbnail.url }}" width="100">
    <h2 class="blog-post-title mb-1">{{ post.title }}</h2>
    <p class="blog-post-meta">{{ post.created_on.date }}</p>
    <p>Categories : 
    {% for category in post.categories.all %}
        <small class="px-1">
            <a href="{% url 'blog_category' category.name %}"> {{ category.name }} </a>
        </small>
    {% endfor %}
    <small class="px-1">
        <a href="{% url 'blog_index' %}"> See All Posts </a>
    </small>   
    </p>
    <div class="post-body my-4">
        {% autoescape off %}
        {{ post.body | safe }}
        {% endautoescape %}
    </div>
</article>
{% endblock post %}

</div>

{% endblock page_content %}

Modify file “myblog/blog/urls.py”.

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

urlpatterns = [
    path('', views.blog_index, name="blog_index"),
    path('post/<int:pk>/', views.blog_details, name='blog_details'),
    path("category/<category>/", views.blog_category, name="blog_category"),
] + static( settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

Make sure you save all the changes. Run the app from terminal and make sure you are in root folder “myblog”.

This how it looks now on our back end. Notice the new input at the bottom, Image File.

This what thumbnail looks like in the front end

Ok that’s it for now.

Leave a Comment