Timeline and Search

Build a following timeline, paginate feeds, and search posts and people.

Goal for this part

Home becomes a following timeline for signed-in people, with a public “Everyone” tab for discovery. Paginate both. Add search for posts and neighbors.

Concepts

The following feed is one SQL query: posts whose author is in the set you follow, plus your own posts. That is not a ranking model. It is honest and indexable. Search uses PostgreSQL icontains first; you can add SearchVector later without changing the URL.

Walkthrough

from django.core.paginator import Paginator

def feed(request):
    scope = request.GET.get("scope", "following")
    qs = Post.objects.select_related("author", "author__profile")
    if request.user.is_authenticated and scope != "everyone":
        people = list(request.user.following.values_list("following_id", flat=True))
        people.append(request.user.id)
        qs = qs.filter(author_id__in=people)
    page = Paginator(qs, 10).get_page(request.GET.get("page"))
    return render(request, "posts/feed.html", {"page": page, "scope": scope})
def search(request):
    q = (request.GET.get("q") or "").strip()[:80]
    posts = Post.objects.none()
    people = User.objects.none()
    if q:
        posts = Post.objects.filter(body__icontains=q)[:20]
        people = User.objects.filter(
            models.Q(username__icontains=q) | models.Q(profile__display_name__icontains=q)
        )[:20]
    return render(request, "social/search.html", {"q": q, "posts": posts, "people": people})

Always cap q. Unbounded search strings are a cheap way to hurt Postgres. Use GET so results are shareable and refresh-safe.

How to run it and what you should see

Sign in as Ada (she follows Grace in the seed). Home should show Grace’s posts and Ada’s, not every seeded stranger. Switch to Everyone and paginate to page 2. Search block and see matching posts; search grace and see her profile in the people list.

Common mistakes

Using Python to filter a huge list instead of author_id__in will not scale. Forgetting your own id in the following set hides your just-composed post. Putting search on POST breaks the back button.

Try this

Unfollow Grace as Ada and confirm her posts leave the Following tab but remain on Everyone. Then add an index in a migration on Post.created_at if it is not there already.