Django Lesson 6: Forms
Django forms handle validation, rendering, and CSRF protection. Model forms generate forms directly from models.
ModelForm
# posts/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ["title", "content", "category", "status"]
widgets = {
"title": forms.TextInput(attrs={"class": "form-input", "placeholder": "Post title"}),
"content": forms.Textarea(attrs={"rows": 8}),
}
Using Forms in Views
# posts/views.py
def create_post(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user # attach logged-in user
post.save()
return redirect("post-detail", slug=post.slug)
else:
form = PostForm()
return render(request, "posts/create.html", {"form": form})
def edit_post(request, pk):
post = get_object_or_404(Post, pk=pk)
form = PostForm(request.POST or None, instance=post) # pre-fill!
if form.is_valid():
form.save()
return redirect("post-detail", slug=post.slug)
return render(request, "posts/edit.html", {"form": form, "post": post})
In Template
<!-- posts/create.html -->
<form method="post">
{% csrf_token %} {# REQUIRED for POST forms #}
{{ form.as_div }}
<button type="submit">Publish</button>
</form>
🏋️ Practice Task
Add forms to your task manager: CreateTaskForm (title, description, project, due_date, priority), EditTaskForm (same + done checkbox). Views: /tasks/create/ and /tasks/
💡 Hint: Validate future date: def clean_due_date(self): date = self.cleaned_data[“due_date”]; if date < timezone.now().date(): raise forms.ValidationError("Must be in the future")