Someone Else's Note
Part of the Users and Accounts section of Coddy's Django journey. Lesson 10 of 16.
The list hides other people's notes, but the note pages do not. Notes are numbered /1/, /2/, /3/, so anyone can try the next number and read it. A list that hides links is not enough: each page has to check.
get_object_or_404() takes the same lookups as filter(), as many as you like, and finds a row only when all of them match. A shop page shows only orders that are still open:
order = get_object_or_404(Order, pk=pk, status="open")A closed order answers 404 Page not found there, the same answer as a number that does not exist. For a private row that is on purpose: a 403 Forbidden would tell a stranger that the row exists.
Order.objects.get() would raise DoesNotExist instead, and the visitor would get a 500 Server Error, a crash.
Challenge
EasyIn note_detail, show a note only to its owner. Someone else's note, and a number that does not exist, both answer 404.
Press Run, log in as bob (password coddy-pass-123) and open /1/, one of ada's notes.
Try it yourself
from django.contrib.auth import login
from django.contrib.auth.decorators import login_not_required
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import get_object_or_404, redirect, render
from .forms import NoteForm
from .models import Note
def note_list(request):
notes = Note.objects.filter(owner=request.user)
return render(request, "notes/note_list.html", {"notes": notes})
def note_detail(request, pk):
note = get_object_or_404(Note, pk=pk)
return render(request, "notes/note_detail.html", {"note": note})
def note_create(request):
if request.method == "POST":
form = NoteForm(request.POST)
if form.is_valid():
note = form.save(commit=False)
note.owner = request.user
note.save()
return redirect("notes:detail", pk=note.pk)
else:
form = NoteForm()
return render(request, "notes/note_form.html", {"form": form})
def note_edit(request, pk):
note = get_object_or_404(Note, pk=pk)
if request.method == "POST":
form = NoteForm(request.POST, instance=note)
if form.is_valid():
form.save()
return redirect("notes:detail", pk=note.pk)
else:
form = NoteForm(instance=note)
return render(request, "notes/note_form.html", {"form": form, "note": note})
def note_delete(request, pk):
note = get_object_or_404(Note, pk=pk)
if request.method == "POST":
note.delete()
return redirect("notes:list")
return render(request, "notes/note_confirm_delete.html", {"note": note})
@login_not_required
def signup(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect("notes:list")
else:
form = UserCreationForm()
return render(request, "notes/signup.html", {"form": form})
All lessons in Users and Accounts
Practice on your own: Django playground