DEV Community

Cover image for Week 2 - Creating Simple Blog App
Jaylord Vhan Fabor
Jaylord Vhan Fabor

Posted on

Week 2 - Creating Simple Blog App

Introduction

Welcome back to my journey of building a blog app using Django without using ChatGPT. This week, I focused on implementing key features to enhance my blog app. I added a functionality that allow users to create posts, comment on posts, and like other user's posts.

Here's a detailed breakdown of what I did:

Create Django posts app

python manage.py startapp posts
Enter fullscreen mode Exit fullscreen mode

Designing the Post Model

I started by designing the Post model. This model will store the blog posts created by users:

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone


class Post(models.Model):
    title = models.CharField(max_length=100)
    description = models.CharField(max_length=200, help_text="Excerpt of the post...")
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    publication_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

Designing the Comment and Like Model

Next, I created as well the Comment and Like models to allow users to leave comment and like on posts:

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f"Comment by {self.author} on {self.post}"


class Like(models.Model):
    post = models.ForeignKey(Post, related_name="likes", on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f"Like by {self.user} on {self.post}"
Enter fullscreen mode Exit fullscreen mode

Creating Views

I will not include the templates as well. I created views for creating, listing all posts and displaying individual posts:

from django.shortcuts import render, redirect, get_object_or_404
from rest_framework import generics
from django.contrib.auth.decorators import login_required
from .serializer import PostSerializer
from .forms import *
from .models import *

def create_post(request):
    if request.method == "POST":
        form = PostForm(request.POST)
        if form.is_valid():
            newPost = form.save(commit=False)
            newPost.author = request.user
            newPost.save()
            return redirect("posts:my-posts")
    else:
        form = PostForm()
    return render(request, "create_post.html", {"form": form, "show_header": True})

@login_required
def myPosts(request):
    '''
    List the user created posts
    '''
    posts = Post.objects.filter(author=request.user)
    return render(request, "posts_list.html", {"posts": posts, "show_header": True})

def postDetails(request, pk):
    '''
    List all posts in the dashboard and display the comments and likes
    '''
    post = get_object_or_404(Post, pk=pk)
    comment = post.comments.all()
    likes = post.likes.count()
    user_has_liked = post.likes.filter(user=request.user).exists()

    if request.method == "POST":
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            comment = comment_form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect("posts:post-detail", pk=post.pk)
    else:
        comment_form = CommentForm()
    return render(
        request,
        "main_post.html",
        {
            "post": post,
            "comments": comment,
            "comment_form": comment_form,
            "likes": likes,
            "user_has_liked": user_has_liked,
        },
    )

@login_required
def like_post(request, pk):
    '''
    Handle liking posts
    '''
    post = get_object_or_404(Post, pk=pk)
    like, created = Like.objects.get_or_create(post=post, user=request.user)
    if not created:
        like.delete()
    return redirect("posts:post-detail", pk=post.pk)
Enter fullscreen mode Exit fullscreen mode

Next is the creating urls.py in a posts app

from django.urls import path
from .views import *

app_name = "posts"

urlpatterns = [
    path("createpost/", create_post, name="create-post"),
    path("post/<int:pk>/", postDetails, name="post-detail"),
    path("post/<int:pk>/like/", like_post, name="like-post"),
    path("myposts/", myPosts, name="my-posts"),
]
Enter fullscreen mode Exit fullscreen mode

Challenges and Learnings

This week, I encountered challenges with:

  • Ensuring the like button allow users to like a post once.
  • Creating form submissions for comments within the post detail view.

Despite these challenges, I learned a lot about handling user interactions and working with Django’s ORM to manage relationships between models.

And that makes my Simple Blog App. Check my Github for more details and a live demo of the app.

Next Week's Goals

I plan to create another Django project to improve my skills and knowledge.

If you have any idea what is a good project to work on or a collaboration on a Django project, please feel free to leave a comment.

Stay tuned for more updates on my journey!

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post →

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay