Session Overview

  • Create Home Page
  • Display Latest Blog Posts
  • Blog Details Page
  • Render CKEditor Content
  • Dynamic Category Menu

Create Home Page

The Home Page displays all published Blog Posts in a professional Bootstrap card layout.

Only posts marked as IsPublished=True should be visible on the website.

Step 1 - Update views.py
from django.shortcuts import render

from .models import Post


def home(request):

    posts = Post.objects.filter(
        IsPublished=True
    ).order_by('-PublishDate')

    return render(
        request,
        'home.html',
        {
            'posts': posts
        }
    )
Step 2 - Update blog/urls.py
from django.urls import path

from . import views

urlpatterns = [

    path('', views.home, name='home'),

]
Explanation
  • filter() displays only published Blog Posts.
  • order_by('-PublishDate') displays the latest posts first.
  • The QuerySet is passed to the template using the posts variable.

Display Latest Blog Posts

We will display all published Blog Posts using a responsive Bootstrap Card layout.

Each card displays the Featured Image, Category, Title, Summary, Publish Date and a Read More button.

Update home.html
{% extends 'base.html' %}

{% block content %}

<div class="container mt-5">

    <div class="text-center mb-5">

        <h1>Django Blog Portal</h1>

        <p class="text-muted">
            Learn • Explore • Build with Django
        </p>

    </div>

    <div class="row">

        {% for post in posts %}

        <div class="col-md-4 mb-4">

            <div class="card h-100 shadow-sm">

                <img src="{{ post.Image.url }}"
                     class="card-img-top"
                     alt="{{ post.Title }}">

                <div class="card-body">

                    <span class="badge bg-primary">
                        {{ post.Category }}
                    </span>

                    <h5 class="card-title mt-3">
                        {{ post.Title }}
                    </h5>

                    <p class="card-text">
                        {{ post.Summary }}
                    </p>

                </div>

                <div class="card-footer bg-white border-0">

                    <small class="text-muted">

                        {{ post.PublishDate }}

                    </small>

                    <a href="#"
                       class="btn btn-primary btn-sm float-end">

                        Read More

                    </a>

                </div>

            </div>

        </div>

        {% empty %}

        <div class="col-12">

            <div class="alert alert-warning">

                No Blog Posts Available.

            </div>

        </div>

        {% endfor %}

    </div>

</div>

{% endblock %}
New Template Tags
Tag Purpose
{% for %} Loops through all Blog Posts.
{{ post.Image.url }} Displays the uploaded Featured Image.
{{ post.Category }} Displays the Category Name.
{% empty %} Displays a message when no Blog Posts are available.

Blog Details Page

When a user clicks the Read More button, the complete Blog Article should be displayed.

We will use the Slug field to create SEO-friendly URLs.

Step 1 - Update blog/urls.py
from django.urls import path

from . import views

urlpatterns = [

    path('', views.home, name='home'),

    path(
        'post/<slug:slug>/',
        views.blogDetails,
        name='blogdetails'
    ),

]
Step 2 - Update views.py
from django.shortcuts import (
    render,
    get_object_or_404
)

from .models import Post


def blogDetails(request, slug):

    post = get_object_or_404(
        Post,
        Slug=slug,
        IsPublished=True
    )

    return render(
        request,
        'blogdetails.html',
        {
            'post': post
        }
    )
Step 3 - Update Read More Button
<a href="{% url 'blogdetails' post.Slug %}"
   class="btn btn-primary btn-sm float-end">

    Read More

</a>
Why do we use Slug?

Instead of opening a Blog using an Id such as /post/1, Django generates a readable URL like /post/learning-django-orm/. This is easier to understand and is better for SEO.

Display Complete Blog Article

Create a new template named blogdetails.html to display the complete Blog Post.

Create blogdetails.html
{% extends 'base.html' %}

{% block content %}

<div class="container mt-5">

    <img src="{{ post.Image.url }}"
         class="img-fluid rounded mb-4"
         alt="{{ post.Title }}">

    <span class="badge bg-primary">

        {{ post.Category }}

    </span>

    <h2 class="mt-3">

        {{ post.Title }}

    </h2>

    <p class="text-muted">

        Published on {{ post.PublishDate }}

    </p>

    <hr>

    {{ post.Description|safe }}

</div>

{% endblock %}
Understanding the safe Filter
{{ post.Description|safe }}

CKEditor stores formatted HTML content in the database.

The safe filter tells Django to render the HTML instead of displaying it as plain text.

Quick Revision

Home Page
  • QuerySet
  • filter()
  • order_by()
Templates
  • for Loop
  • empty
  • Template Variables
Blog Details
  • Slug
  • get_object_or_404()
  • Named URL
CKEditor
  • RichTextField
  • safe Filter
  • Formatted Content
Images
  • ImageField
  • Image.url
  • Media Folder
Dynamic Content
  • Category Menu
  • Dynamic Navbar
  • Database Driven UI
Concepts Learned Today
✓ Display QuerySets

✓ Bootstrap Card Layout

✓ Dynamic URLs using Slug

✓ get_object_or_404()

✓ Render CKEditor Content

✓ Dynamic Category Menu

Assignment

Continue Developing the News Portal

Implement the same frontend functionality covered in today's Blog Project using your News Portal.

  1. Create a Home Page that displays all published News Articles.
  2. Display News Articles using Bootstrap Cards showing:
    • Featured Image
    • Category
    • Title
    • Summary
    • Publish Date
    • Read More Button
  3. Create a News Details page using the Slug field.
  4. Display the complete News Article using the safe filter to render CKEditor content.
  5. Handle invalid News URLs using get_object_or_404().
  6. Display all News Categories dynamically in the Navigation Menu.
  7. Verify that only published News Articles are displayed on the Home Page.
  8. Test the complete navigation:
    • Home Page → Read More
    • News Details → Back to Home