from django.contrib import messages from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, redirect, render from django.utils import timezone from django.utils.text import slugify from django.views.decorators.http import require_http_methods, require_POST from blog.models import Post def post_list(request): posts = Post.objects.filter(is_published=True) return render(request, "blog/list.html", {"posts": posts}) def post_detail(request, slug): post = get_object_or_404(Post, slug=slug, is_published=True) return render(request, "blog/detail.html", {"post": post}) @login_required def portal_list(request): posts = Post.objects.all() return render(request, "blog/portal/list.html", {"posts": posts}) @login_required @require_http_methods(["GET", "POST"]) def portal_edit(request, pk=None): post = get_object_or_404(Post, pk=pk) if pk else None if request.method == "POST": title = (request.POST.get("title") or "").strip() body = (request.POST.get("body") or "").strip() excerpt = (request.POST.get("excerpt") or "").strip() slug = (request.POST.get("slug") or "").strip() is_published = request.POST.get("is_published") == "on" if not title or not body: messages.error(request, "Title and body are required.") else: if post is None: post = Post(author=request.user) post.title = title post.body = body post.excerpt = excerpt post.slug = slugify(slug)[:220] if slug else "" post.is_published = is_published if is_published and post.published_at is None: post.published_at = timezone.now() if not is_published: post.published_at = None post.save() messages.success(request, f'Saved “{post.title}”.') return redirect("blog_portal:portal_list") return render(request, "blog/portal/edit.html", {"post": post}) @login_required @require_POST def portal_delete(request, pk): post = get_object_or_404(Post, pk=pk) title = post.title post.delete() messages.success(request, f'Deleted “{title}”.') return redirect("blog_portal:portal_list")