Feed and Detail

Render a public post feed and permalink pages from the database.

Goal for this part

Replace placeholder text with a public feed and a permalink for each post. Guests can read. Writes wait until login exists.

Concepts

A social feed is a query, not a magic algorithm. For now the public home page is “latest posts from everyone,” newest first, with author name and relative time. The following timeline comes in part 10. select_related and prefetch_related keep that query from becoming N+1 once avatars and like counts appear.

Walkthrough

# posts/views.py
from django.shortcuts import get_object_or_404, render
from .models import Post

def feed(request):
    posts = (
        Post.objects.select_related("author", "author__profile")
        .prefetch_related("likes", "comments")
    )
    return render(request, "posts/feed.html", {"posts": posts})

def detail(request, slug):
    post = get_object_or_404(
        Post.objects.select_related("author", "author__profile"),
        slug=slug,
    )
    return render(request, "posts/detail.html", {"post": post})

Each card links to the author profile (stub for now) and to posts:detail. Keep the body to 500 characters — Westloop is a neighborhood update, not a blog CMS.

How to run it and what you should see

Open /. Seeded posts from Ada and Grace should appear as cards. Click a timestamp or “Open” link and land on /p/<slug>/ with the full body and a comment list heading (empty until part 9).

Common mistakes

Forgetting select_related("author__profile") will query once per card once avatars exist. A missing slug in the seed data 404s the detail page. Do not put compose-box HTML on this snapshot — guests should not see a form that 403s.

Try this

Add a like count and comment count to each card using the prefetched relations. Confirm the home page still does a handful of SQL queries, not one per post, by watching django.db.backends logging.