NelsonLabs
Django/Project: Blog with CRUD

Project: Blog with CRUD

Build a full blog with CRUD โ€” create, read, update, and delete posts. Users can register, log in, write posts, and edit their own content. This is a complete, deployable Django application.

models.py โ€” blog post model
python
class Post(models.Model):
    title      = models.CharField(max_length=200)
    slug       = models.SlugField(unique=True)
    author     = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
    body       = models.TextField()
    published  = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse("post-detail", kwargs={"slug": self.slug})
views.py โ€” CRUD views
python
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.utils.text import slugify
from .models import Post
from .forms  import PostForm

def post_list(request):
    posts = Post.objects.filter(published=True)
    return render(request, "blog/list.html", {"posts": posts})

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug, published=True)
    return render(request, "blog/detail.html", {"post": post})

@login_required
def post_create(request):
    form = PostForm(request.POST or None)
    if form.is_valid():
        post       = form.save(commit=False)
        post.author = request.user
        post.slug   = slugify(post.title)
        post.save()
        return redirect(post.get_absolute_url())
    return render(request, "blog/form.html", {"form": form, "action": "Create"})

@login_required
def post_edit(request, slug):
    post = get_object_or_404(Post, slug=slug, author=request.user)
    form = PostForm(request.POST or None, instance=post)
    if form.is_valid():
        form.save()
        return redirect(post.get_absolute_url())
    return render(request, "blog/form.html", {"form": form, "action": "Edit"})

@login_required
def post_delete(request, slug):
    post = get_object_or_404(Post, slug=slug, author=request.user)
    if request.method == "POST":
        post.delete()
        return redirect("post-list")
    return render(request, "blog/confirm_delete.html", {"post": post})